threads / patch / 39492

patchgitk: Alter the ordering for the "Tags and heads" view

Subject: [PATCH] gitk: Alter the ordering for the "Tags and heads" view

## tl;dr

3 messages between Jun 2, 2015 and Aug 13, 2015. Diffs are folded; open one to read it.

replies: 2people: 2as markdown or json

Michael Rappazzo· Jun 2, 2015, 11:11 UTC · lore

In a codebase with a large number of remote branches, the "Tags and heads" view can split the local refs around the name "remotes". I wanted to make this view more useful as a quick view of the refs that are important to me at the moment (I would say the branches that I am actively looking at).

Therefore, I have made this change to the ordering of the view. It should show up in the following order:

    local refs
    remote refs which are tracked (upstream) by local refs
    remote refs
    tags
    other refs

Each of these lists is independently sorted before being put into the main ref list. Also note that the upstream refs are _not_ duplicated in the remote refs list.

Michael Rappazzo (1):
  gitk: Alter the ordering for the "Tags and heads" view
 gitk-git/gitk | 48 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 6 deletions(-)
-- 
2.4.2
Michael Rappazzo· Jun 2, 2015, 11:11 UTC · re: Michael Rappazzo · lore

In the "Tags and heads" view, the list of refs is globally sorted. The list of local refs (heads) is separated by the remote refs. This change re-orders the view toi 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-git/gitk | 48 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 42 insertions(+), 6 deletions(-)
Show changes to gitk-git/gitk +42 −6
diff --git a/gitk-git/gitk b/gitk-git/gitk
index 9a2daf3..431a6a1 100755
--- a/gitk-git/gitk
+++ b/gitk-git/gitk
@@ -9879,35 +9879,71 @@ proc refill_reflist {} {
     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 localrefs [list $n H]
+		catch {set remote_name [exec git config --get branch.$n.remote]}
+		if {$remote_name ne ""} {
+		    catch {set remote_ref [exec git config --get branch.$n.merge]}
+		    set remote_ref [string map {"refs/heads/" ""} $remote_ref]
+		    set locally_tracked_remote_ref "remotes/$remote_name/$remote_ref"
+		    catch {set exists [exec git rev-parse --verify $locally_tracked_remote_ref]}
+		    if {$exists ne ""} {
+			if {[lsearch $locally_tracked_remote_refs [list $locally_tracked_remote_ref H]] < 0} {
+			    lappend locally_tracked_remote_refs [list $locally_tracked_remote_ref H]
+			}
+		    }
+		    set exists ""
+		}
+	    } 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]} {
-		lappend refs [list $n H]
+		if {[lsearch $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.4.2
Paul Mackerras· Aug 13, 2015, 00:43 UTC · re: Michael Rappazzo · lore

Re: [PATCH] gitk: Alter the ordering for the "Tags and heads" view

On Tue, Jun 02, 2015 at 07:11:10AM -0400, Michael Rappazzo wrote:
Show 6 quoted lines
> In the "Tags and heads" view, the list of refs is globally sorted.
> The list of local refs (heads) is separated by the remote refs.  This
> change re-orders the view toi be: local refs, remote refs tracked by
> local refs, remote refs, tags, and then other refs
> 
> Signed-off-by: Michael Rappazzo <rappazzo@gmail.com>

Sorry it's taken me so long to get around to reviewing this. I have a couple of comments:

Show 25 quoted lines
> ---
>  gitk-git/gitk | 48 ++++++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 42 insertions(+), 6 deletions(-)
> 
> diff --git a/gitk-git/gitk b/gitk-git/gitk
> index 9a2daf3..431a6a1 100755
> --- a/gitk-git/gitk
> +++ b/gitk-git/gitk
> @@ -9879,35 +9879,71 @@ proc refill_reflist {} {
>      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 localrefs [list $n H]
> +		catch {set remote_name [exec git config --get branch.$n.remote]}
> +		if {$remote_name ne ""} {

First off, if the git config command fails for any reason and returns an error status, the set command won't get done and $remote_name will either be undefined or will have whatever value it had before. If it is undefined then the if statement is going to throw an error. I don't think that is what you meant to happen. This same problem will occur for other variables such as $remote_ref and $exists.

Secondly, I'm not very happy about doing all these external git commands every time we run refill_reflist. Couldn't we cache which remote each local branch is tracking? We would then throw away and reload the cache in rereadrefs. Most executions of refill_reflist would then not need to do any external git commands at all.

Paul.

← back to recent threads