git-gui: Maintain remote and source ref for tracking branches
authorShawn O. Pearce <spearce@spearce.org>
Wed, 4 Jul 2007 05:10:41 +0000 (01:10 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Mon, 9 Jul 2007 01:12:49 +0000 (21:12 -0400)
In the next change I want to let the user create their local branch
name to match the remote branch name, so that the existing push
dialog can push the branch back up to the remote repository without
needing to do any sort of remapping.  To do that we need to know
exactly what branch name the remote system is using.

So all_tracking_branches returns a list of specifications, where
each specification is itself a list of:

  - local ref name (destination we fetch into)
  - remote name (repository we fetch from)
  - remote ref name (source ref we fetch from)

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
lib/choose_rev.tcl
lib/remote.tcl

index 01e8efe991599901a5b90b65ec333a3063af635d..b3b615ee42d6e54058c5140fc3cb89d000ebcf2e 100644 (file)
@@ -11,6 +11,8 @@ field c_trck        {}; # selected tracking branch
 field c_tag         {}; # selected tag
 field c_expr        {}; # current revision expression
 
+field trck_spec       ; # array of specifications
+
 constructor new {path {title {}}} {
        global all_heads current_branch
 
@@ -37,19 +39,30 @@ constructor new {path {title {}}} {
                trace add variable @c_head write [cb _select head]
        }
 
-       set all_trackings [all_tracking_branches]
-       if {$all_trackings ne {}} {
-               set c_trck [lindex $all_trackings 0]
+       set trck_list [all_tracking_branches]
+       if {$trck_list ne {}} {
+               set nam [list]
+               foreach spec $trck_list {
+                       set txt [lindex $spec 0]
+                       regsub ^refs/(heads/|remotes/)? $txt {} txt
+                       set trck_spec($txt) $spec
+                       lappend nam $txt
+               }
+               set nam [lsort -unique $nam]
+
                radiobutton $w.trck_r \
                        -text {Tracking Branch:} \
                        -value trck \
                        -variable @revtype
-               eval tk_optionMenu $w.trck_m @c_trck $all_trackings
+               eval tk_optionMenu $w.trck_m @c_trck $nam
                grid $w.trck_r $w.trck_m -sticky w
+
+               set c_trck [lindex $nam 0]
                if {$revtype eq {}} {
                        set revtype trck
                }
                trace add variable @c_trck write [cb _select trck]
+               unset nam spec txt
        }
 
        set all_tags [load_all_tags]
@@ -115,12 +128,22 @@ method get {} {
        }
 }
 
+method get_expr {} {
+       switch -- $revtype {
+       head { return refs/heads/$c_head             }
+       trck { return [lindex $trck_spec($c_trck) 0] }
+       tag  { return refs/tags/$c_tag               }
+       expr { return $c_expr                        }
+       none { return {}                             }
+       default { error "unknown type of revision"   }
+       }
+}
+
 method get_commit {} {
        if {$revtype eq {none}} {
                return {}
        }
-       set rev [get $this]
-       return [git rev-parse --verify "${rev}^0"]
+       return [git rev-parse --verify "[get_expr $this]^0"]
 }
 
 method _validate {d S} {
index 55a6dc33011701902f12c9af575074808bbcbcba..fabec05fff3edb1e1709b2557ec0ede1470ec7ae 100644 (file)
@@ -17,28 +17,41 @@ proc is_tracking_branch {name} {
 proc all_tracking_branches {} {
        global tracking_branches
 
-       set all_trackings {}
-       set cmd {}
+       set all [list]
+       set pat [list]
+       set cmd [list]
+
        foreach spec $tracking_branches {
-               set name [lindex $spec 0]
-               if {[string range $name end-1 end] eq {/*}} {
-                       lappend cmd [string range $name 0 end-2]
+               set dst [lindex $spec 0]
+               if {[string range $dst end-1 end] eq {/*}} {
+                       lappend pat $spec
+                       lappend cmd [string range $dst 0 end-2]
                } else {
-                       regsub ^refs/(heads|remotes)/ $name {} name
-                       lappend all_trackings $name
+                       lappend all $spec
                }
        }
 
-       if {$cmd ne {}} {
+       if {$pat ne {}} {
                set fd [open "| git for-each-ref --format=%(refname) $cmd" r]
-               while {[gets $fd name] > 0} {
-                       regsub ^refs/(heads|remotes)/ $name {} name
-                       lappend all_trackings $name
+               while {[gets $fd n] > 0} {
+                       foreach spec $pat {
+                               set dst [string range [lindex $spec 0] 0 end-2]
+                               set len [string length $dst]
+                               if {[string equal -length $len $dst $n]} {
+                                       set src [string range [lindex $spec 2] 0 end-2]
+                                       set spec [list \
+                                               $n \
+                                               [lindex $spec 1] \
+                                               $src[string range $n $len end] \
+                                               ]
+                                       lappend all $spec
+                               }
+                       }
                }
                close $fd
        }
 
-       return [lsort -unique $all_trackings]
+       return [lsort -index 0 -unique $all]
 }
 
 proc load_all_remotes {} {
@@ -65,6 +78,9 @@ proc load_all_remotes {} {
                                while {[gets $fd line] >= 0} {
                                        if {![regexp {^Pull:[   ]*([^:]+):(.+)$} \
                                                $line line src dst]} continue
+                                       if {[string index $src 0] eq {+}} {
+                                               set src [string range $src 1 end]
+                                       }
                                        if {![string equal -length 5 refs/ $src]} {
                                                set src $rh_str$src
                                        }
@@ -90,6 +106,9 @@ proc load_all_remotes {} {
                }
                foreach line $fl {
                        if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue
+                       if {[string index $src 0] eq {+}} {
+                               set src [string range $src 1 end]
+                       }
                        if {![string equal -length 5 refs/ $src]} {
                                set src $rh_str$src
                        }