git-gui: Maintain remote and source ref for tracking branches

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>
This commit is contained in:
Shawn O. Pearce
2007-07-04 01:10:41 -04:00
parent 6f2a3fc812
commit 79a060e477
2 changed files with 60 additions and 18 deletions

View File

@ -11,6 +11,8 @@ field c_trck {}; # selected tracking branch
field c_tag {}; # selected tag field c_tag {}; # selected tag
field c_expr {}; # current revision expression field c_expr {}; # current revision expression
field trck_spec ; # array of specifications
constructor new {path {title {}}} { constructor new {path {title {}}} {
global all_heads current_branch global all_heads current_branch
@ -37,19 +39,30 @@ constructor new {path {title {}}} {
trace add variable @c_head write [cb _select head] trace add variable @c_head write [cb _select head]
} }
set all_trackings [all_tracking_branches] set trck_list [all_tracking_branches]
if {$all_trackings ne {}} { if {$trck_list ne {}} {
set c_trck [lindex $all_trackings 0] 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 \ radiobutton $w.trck_r \
-text {Tracking Branch:} \ -text {Tracking Branch:} \
-value trck \ -value trck \
-variable @revtype -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 grid $w.trck_r $w.trck_m -sticky w
set c_trck [lindex $nam 0]
if {$revtype eq {}} { if {$revtype eq {}} {
set revtype trck set revtype trck
} }
trace add variable @c_trck write [cb _select trck] trace add variable @c_trck write [cb _select trck]
unset nam spec txt
} }
set all_tags [load_all_tags] 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 {} { method get_commit {} {
if {$revtype eq {none}} { if {$revtype eq {none}} {
return {} return {}
} }
set rev [get $this] return [git rev-parse --verify "[get_expr $this]^0"]
return [git rev-parse --verify "${rev}^0"]
} }
method _validate {d S} { method _validate {d S} {

View File

@ -17,28 +17,41 @@ proc is_tracking_branch {name} {
proc all_tracking_branches {} { proc all_tracking_branches {} {
global tracking_branches global tracking_branches
set all_trackings {} set all [list]
set cmd {} set pat [list]
set cmd [list]
foreach spec $tracking_branches { foreach spec $tracking_branches {
set name [lindex $spec 0] set dst [lindex $spec 0]
if {[string range $name end-1 end] eq {/*}} { if {[string range $dst end-1 end] eq {/*}} {
lappend cmd [string range $name 0 end-2] lappend pat $spec
lappend cmd [string range $dst 0 end-2]
} else { } else {
regsub ^refs/(heads|remotes)/ $name {} name lappend all $spec
lappend all_trackings $name
} }
} }
if {$cmd ne {}} { if {$pat ne {}} {
set fd [open "| git for-each-ref --format=%(refname) $cmd" r] set fd [open "| git for-each-ref --format=%(refname) $cmd" r]
while {[gets $fd name] > 0} { while {[gets $fd n] > 0} {
regsub ^refs/(heads|remotes)/ $name {} name foreach spec $pat {
lappend all_trackings $name 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 close $fd
} }
return [lsort -unique $all_trackings] return [lsort -index 0 -unique $all]
} }
proc load_all_remotes {} { proc load_all_remotes {} {
@ -65,6 +78,9 @@ proc load_all_remotes {} {
while {[gets $fd line] >= 0} { while {[gets $fd line] >= 0} {
if {![regexp {^Pull:[ ]*([^:]+):(.+)$} \ if {![regexp {^Pull:[ ]*([^:]+):(.+)$} \
$line line src dst]} continue $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]} { if {![string equal -length 5 refs/ $src]} {
set src $rh_str$src set src $rh_str$src
} }
@ -90,6 +106,9 @@ proc load_all_remotes {} {
} }
foreach line $fl { foreach line $fl {
if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue 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]} { if {![string equal -length 5 refs/ $src]} {
set src $rh_str$src set src $rh_str$src
} }