]> asedeno.scripts.mit.edu Git - git.git/blob - lib/remote.tcl
git-gui: Optimize for newstyle refs/remotes layout
[git.git] / lib / remote.tcl
1 # git-gui remote management
2 # Copyright (C) 2006, 2007 Shawn Pearce
3
4 set some_heads_tracking 0;  # assume not
5
6 proc is_tracking_branch {name} {
7         global tracking_branches
8         foreach spec $tracking_branches {
9                 set t [lindex $spec 0]
10                 if {$t eq $name || [string match $t $name]} {
11                         return 1
12                 }
13         }
14         return 0
15 }
16
17 proc all_tracking_branches {} {
18         global tracking_branches
19
20         set all_trackings {}
21         set cmd {}
22         foreach spec $tracking_branches {
23                 set name [lindex $spec 0]
24                 if {[string range $name end-1 end] eq {/*}} {
25                         lappend cmd [string range $name 0 end-2]
26                 } else {
27                         regsub ^refs/(heads|remotes)/ $name {} name
28                         lappend all_trackings $name
29                 }
30         }
31
32         if {$cmd ne {}} {
33                 set fd [open "| git for-each-ref --format=%(refname) $cmd" r]
34                 while {[gets $fd name] > 0} {
35                         regsub ^refs/(heads|remotes)/ $name {} name
36                         lappend all_trackings $name
37                 }
38                 close $fd
39         }
40
41         return [lsort -unique $all_trackings]
42 }
43
44 proc load_all_remotes {} {
45         global repo_config
46         global all_remotes tracking_branches some_heads_tracking
47
48         set some_heads_tracking 0
49         set all_remotes [list]
50         set trck [list]
51
52         set rh_str refs/heads/
53         set rh_len [string length $rh_str]
54         set rm_dir [gitdir remotes]
55         if {[file isdirectory $rm_dir]} {
56                 set all_remotes [glob \
57                         -types f \
58                         -tails \
59                         -nocomplain \
60                         -directory $rm_dir *]
61
62                 foreach name $all_remotes {
63                         catch {
64                                 set fd [open [file join $rm_dir $name] r]
65                                 while {[gets $fd line] >= 0} {
66                                         if {![regexp {^Pull:[   ]*([^:]+):(.+)$} \
67                                                 $line line src dst]} continue
68                                         if {![string equal -length 5 refs/ $src]} {
69                                                 set src $rh_str$src
70                                         }
71                                         if {![string equal -length 5 refs/ $dst]} {
72                                                 set dst $rh_str$dst
73                                         }
74                                         if {[string equal -length $rh_len $rh_str $dst]} {
75                                                 set some_heads_tracking 1
76                                         }
77                                         lappend trck [list $dst $name $src]
78                                 }
79                                 close $fd
80                         }
81                 }
82         }
83
84         foreach line [array names repo_config remote.*.url] {
85                 if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue
86                 lappend all_remotes $name
87
88                 if {[catch {set fl $repo_config(remote.$name.fetch)}]} {
89                         set fl {}
90                 }
91                 foreach line $fl {
92                         if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue
93                         if {![string equal -length 5 refs/ $src]} {
94                                 set src $rh_str$src
95                         }
96                         if {![string equal -length 5 refs/ $dst]} {
97                                 set dst $rh_str$dst
98                         }
99                         if {[string equal -length $rh_len $rh_str $dst]} {
100                                 set some_heads_tracking 1
101                         }
102                         lappend trck [list $dst $name $src]
103                 }
104         }
105
106         set tracking_branches [lsort -index 0 -unique $trck]
107         set all_remotes [lsort -unique $all_remotes]
108 }
109
110 proc populate_fetch_menu {} {
111         global all_remotes repo_config
112
113         set m .mbar.fetch
114         set prune_list [list]
115         foreach r $all_remotes {
116                 set enable 0
117                 if {![catch {set a $repo_config(remote.$r.url)}]} {
118                         if {![catch {set a $repo_config(remote.$r.fetch)}]} {
119                                 set enable 1
120                         }
121                 } else {
122                         catch {
123                                 set fd [open [gitdir remotes $r] r]
124                                 while {[gets $fd n] >= 0} {
125                                         if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
126                                                 set enable 1
127                                                 break
128                                         }
129                                 }
130                                 close $fd
131                         }
132                 }
133
134                 if {$enable} {
135                         lappend prune_list $r
136                         $m add command \
137                                 -label "Fetch from $r..." \
138                                 -command [list fetch_from $r]
139                 }
140         }
141
142         if {$prune_list ne {}} {
143                 $m add separator
144         }
145         foreach r $prune_list {
146                 $m add command \
147                         -label "Prune from $r..." \
148                         -command [list prune_from $r]
149         }
150 }
151
152 proc populate_push_menu {} {
153         global all_remotes repo_config
154
155         set m .mbar.push
156         set fast_count 0
157         foreach r $all_remotes {
158                 set enable 0
159                 if {![catch {set a $repo_config(remote.$r.url)}]} {
160                         if {![catch {set a $repo_config(remote.$r.push)}]} {
161                                 set enable 1
162                         }
163                 } else {
164                         catch {
165                                 set fd [open [gitdir remotes $r] r]
166                                 while {[gets $fd n] >= 0} {
167                                         if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
168                                                 set enable 1
169                                                 break
170                                         }
171                                 }
172                                 close $fd
173                         }
174                 }
175
176                 if {$enable} {
177                         if {!$fast_count} {
178                                 $m add separator
179                         }
180                         $m add command \
181                                 -label "Push to $r..." \
182                                 -command [list push_to $r]
183                         incr fast_count
184                 }
185         }
186 }