]>
Commit | Line | Data |
---|---|---|
f522c9b5 SP |
1 | # git-gui remote management |
2 | # Copyright (C) 2006, 2007 Shawn Pearce | |
3 | ||
6f2a3fc8 SP |
4 | set some_heads_tracking 0; # assume not |
5 | ||
f522c9b5 SP |
6 | proc is_tracking_branch {name} { |
7 | global tracking_branches | |
6f2a3fc8 SP |
8 | foreach spec $tracking_branches { |
9 | set t [lindex $spec 0] | |
10 | if {$t eq $name || [string match $t $name]} { | |
f522c9b5 SP |
11 | return 1 |
12 | } | |
13 | } | |
14 | return 0 | |
15 | } | |
16 | ||
17 | proc all_tracking_branches {} { | |
18 | global tracking_branches | |
19 | ||
79a060e4 SP |
20 | set all [list] |
21 | set pat [list] | |
22 | set cmd [list] | |
23 | ||
6f2a3fc8 | 24 | foreach spec $tracking_branches { |
79a060e4 SP |
25 | set dst [lindex $spec 0] |
26 | if {[string range $dst end-1 end] eq {/*}} { | |
27 | lappend pat $spec | |
28 | lappend cmd [string range $dst 0 end-2] | |
f522c9b5 | 29 | } else { |
79a060e4 | 30 | lappend all $spec |
f522c9b5 SP |
31 | } |
32 | } | |
33 | ||
79a060e4 | 34 | if {$pat ne {}} { |
0b812616 | 35 | set fd [eval git_read for-each-ref --format=%(refname) $cmd] |
79a060e4 SP |
36 | while {[gets $fd n] > 0} { |
37 | foreach spec $pat { | |
38 | set dst [string range [lindex $spec 0] 0 end-2] | |
39 | set len [string length $dst] | |
40 | if {[string equal -length $len $dst $n]} { | |
41 | set src [string range [lindex $spec 2] 0 end-2] | |
42 | set spec [list \ | |
43 | $n \ | |
44 | [lindex $spec 1] \ | |
45 | $src[string range $n $len end] \ | |
46 | ] | |
47 | lappend all $spec | |
48 | } | |
49 | } | |
f522c9b5 SP |
50 | } |
51 | close $fd | |
52 | } | |
53 | ||
79a060e4 | 54 | return [lsort -index 0 -unique $all] |
f522c9b5 SP |
55 | } |
56 | ||
57 | proc load_all_remotes {} { | |
58 | global repo_config | |
6f2a3fc8 | 59 | global all_remotes tracking_branches some_heads_tracking |
30d19905 | 60 | global remote_url |
f522c9b5 | 61 | |
6f2a3fc8 | 62 | set some_heads_tracking 0 |
f522c9b5 | 63 | set all_remotes [list] |
6f2a3fc8 | 64 | set trck [list] |
f522c9b5 | 65 | |
6f2a3fc8 SP |
66 | set rh_str refs/heads/ |
67 | set rh_len [string length $rh_str] | |
f522c9b5 SP |
68 | set rm_dir [gitdir remotes] |
69 | if {[file isdirectory $rm_dir]} { | |
70 | set all_remotes [glob \ | |
71 | -types f \ | |
72 | -tails \ | |
73 | -nocomplain \ | |
74 | -directory $rm_dir *] | |
75 | ||
76 | foreach name $all_remotes { | |
77 | catch { | |
78 | set fd [open [file join $rm_dir $name] r] | |
79 | while {[gets $fd line] >= 0} { | |
30d19905 SP |
80 | if {[regexp {^URL:[ ]*(.+)$} $line line url]} { |
81 | set remote_url($name) $url | |
82 | continue | |
83 | } | |
f522c9b5 SP |
84 | if {![regexp {^Pull:[ ]*([^:]+):(.+)$} \ |
85 | $line line src dst]} continue | |
79a060e4 SP |
86 | if {[string index $src 0] eq {+}} { |
87 | set src [string range $src 1 end] | |
88 | } | |
6f2a3fc8 SP |
89 | if {![string equal -length 5 refs/ $src]} { |
90 | set src $rh_str$src | |
91 | } | |
92 | if {![string equal -length 5 refs/ $dst]} { | |
93 | set dst $rh_str$dst | |
f522c9b5 | 94 | } |
6f2a3fc8 SP |
95 | if {[string equal -length $rh_len $rh_str $dst]} { |
96 | set some_heads_tracking 1 | |
97 | } | |
98 | lappend trck [list $dst $name $src] | |
f522c9b5 SP |
99 | } |
100 | close $fd | |
101 | } | |
102 | } | |
103 | } | |
104 | ||
105 | foreach line [array names repo_config remote.*.url] { | |
106 | if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue | |
107 | lappend all_remotes $name | |
30d19905 | 108 | set remote_url($name) $repo_config(remote.$name.url) |
f522c9b5 SP |
109 | |
110 | if {[catch {set fl $repo_config(remote.$name.fetch)}]} { | |
111 | set fl {} | |
112 | } | |
113 | foreach line $fl { | |
114 | if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue | |
79a060e4 SP |
115 | if {[string index $src 0] eq {+}} { |
116 | set src [string range $src 1 end] | |
117 | } | |
6f2a3fc8 SP |
118 | if {![string equal -length 5 refs/ $src]} { |
119 | set src $rh_str$src | |
120 | } | |
121 | if {![string equal -length 5 refs/ $dst]} { | |
122 | set dst $rh_str$dst | |
123 | } | |
124 | if {[string equal -length $rh_len $rh_str $dst]} { | |
125 | set some_heads_tracking 1 | |
f522c9b5 | 126 | } |
6f2a3fc8 | 127 | lappend trck [list $dst $name $src] |
f522c9b5 SP |
128 | } |
129 | } | |
130 | ||
6f2a3fc8 | 131 | set tracking_branches [lsort -index 0 -unique $trck] |
f522c9b5 SP |
132 | set all_remotes [lsort -unique $all_remotes] |
133 | } | |
134 | ||
8329bd07 PB |
135 | proc add_fetch_entry {r} { |
136 | global repo_config | |
6bdf5e5f SP |
137 | set remote_m .mbar.remote |
138 | set fetch_m $remote_m.fetch | |
139 | set prune_m $remote_m.prune | |
0d404412 | 140 | set remove_m $remote_m.remove |
8329bd07 PB |
141 | set enable 0 |
142 | if {![catch {set a $repo_config(remote.$r.url)}]} { | |
143 | if {![catch {set a $repo_config(remote.$r.fetch)}]} { | |
144 | set enable 1 | |
145 | } | |
146 | } else { | |
147 | catch { | |
148 | set fd [open [gitdir remotes $r] r] | |
149 | while {[gets $fd n] >= 0} { | |
150 | if {[regexp {^Pull:[ \t]*([^:]+):} $n]} { | |
151 | set enable 1 | |
152 | break | |
f522c9b5 | 153 | } |
f522c9b5 | 154 | } |
8329bd07 | 155 | close $fd |
f522c9b5 | 156 | } |
8329bd07 | 157 | } |
f522c9b5 | 158 | |
8329bd07 | 159 | if {$enable} { |
e8db4035 | 160 | make_sure_remote_submenues_exist $remote_m |
8329bd07 PB |
161 | |
162 | $fetch_m add command \ | |
163 | -label $r \ | |
164 | -command [list fetch_from $r] | |
165 | $prune_m add command \ | |
166 | -label $r \ | |
167 | -command [list prune_from $r] | |
0d404412 PB |
168 | $remove_m add command \ |
169 | -label $r \ | |
170 | -command [list remove_remote $r] | |
f522c9b5 SP |
171 | } |
172 | } | |
173 | ||
8329bd07 PB |
174 | proc add_push_entry {r} { |
175 | global repo_config | |
6bdf5e5f SP |
176 | set remote_m .mbar.remote |
177 | set push_m $remote_m.push | |
8329bd07 PB |
178 | set enable 0 |
179 | if {![catch {set a $repo_config(remote.$r.url)}]} { | |
180 | if {![catch {set a $repo_config(remote.$r.push)}]} { | |
181 | set enable 1 | |
182 | } | |
183 | } else { | |
184 | catch { | |
185 | set fd [open [gitdir remotes $r] r] | |
186 | while {[gets $fd n] >= 0} { | |
187 | if {[regexp {^Push:[ \t]*([^:]+):} $n]} { | |
188 | set enable 1 | |
189 | break | |
f522c9b5 | 190 | } |
f522c9b5 | 191 | } |
8329bd07 | 192 | close $fd |
f522c9b5 | 193 | } |
8329bd07 | 194 | } |
f522c9b5 | 195 | |
8329bd07 PB |
196 | if {$enable} { |
197 | if {![winfo exists $push_m]} { | |
198 | menu $push_m | |
199 | $remote_m insert 0 cascade \ | |
200 | -label [mc "Push to"] \ | |
201 | -menu $push_m | |
f522c9b5 | 202 | } |
8329bd07 PB |
203 | |
204 | $push_m add command \ | |
205 | -label $r \ | |
206 | -command [list push_to $r] | |
207 | } | |
208 | } | |
209 | ||
e8db4035 HV |
210 | proc make_sure_remote_submenues_exist {remote_m} { |
211 | set fetch_m $remote_m.fetch | |
212 | set prune_m $remote_m.prune | |
213 | set remove_m $remote_m.remove | |
214 | ||
215 | if {![winfo exists $fetch_m]} { | |
216 | menu $remove_m | |
217 | $remote_m insert 0 cascade \ | |
218 | -label [mc "Remove Remote"] \ | |
219 | -menu $remove_m | |
220 | ||
221 | menu $prune_m | |
222 | $remote_m insert 0 cascade \ | |
223 | -label [mc "Prune from"] \ | |
224 | -menu $prune_m | |
225 | ||
226 | menu $fetch_m | |
227 | $remote_m insert 0 cascade \ | |
228 | -label [mc "Fetch from"] \ | |
229 | -menu $fetch_m | |
230 | } | |
231 | } | |
232 | ||
69e21b83 HV |
233 | proc update_all_remotes_menu_entry {} { |
234 | global all_remotes | |
235 | ||
ba44692a PT |
236 | if {[git-version < 1.6.6]} { return } |
237 | ||
69e21b83 HV |
238 | set have_remote 0 |
239 | foreach r $all_remotes { | |
4bfa2502 | 240 | incr have_remote |
69e21b83 HV |
241 | } |
242 | ||
243 | set remote_m .mbar.remote | |
244 | set fetch_m $remote_m.fetch | |
245 | set prune_m $remote_m.prune | |
4bfa2502 | 246 | if {$have_remote > 1} { |
69e21b83 | 247 | make_sure_remote_submenues_exist $remote_m |
5c37033e | 248 | if {[$fetch_m type end] eq "command" \ |
ac459b9c | 249 | && [$fetch_m entrycget end -label] ne [mc "All"]} { |
69e21b83 | 250 | |
4c2519e5 HV |
251 | $fetch_m insert end separator |
252 | $fetch_m insert end command \ | |
ac459b9c | 253 | -label [mc "All"] \ |
69e21b83 HV |
254 | -command fetch_from_all |
255 | ||
4c2519e5 HV |
256 | $prune_m insert end separator |
257 | $prune_m insert end command \ | |
ac459b9c | 258 | -label [mc "All"] \ |
69e21b83 HV |
259 | -command prune_from_all |
260 | } | |
261 | } else { | |
262 | if {[winfo exists $fetch_m]} { | |
5c37033e | 263 | if {[$fetch_m type end] eq "command" \ |
ac459b9c | 264 | && [$fetch_m entrycget end -label] eq [mc "All"]} { |
69e21b83 | 265 | |
4c2519e5 HV |
266 | delete_from_menu $fetch_m end |
267 | delete_from_menu $fetch_m end | |
69e21b83 | 268 | |
4c2519e5 HV |
269 | delete_from_menu $prune_m end |
270 | delete_from_menu $prune_m end | |
69e21b83 HV |
271 | } |
272 | } | |
273 | } | |
274 | } | |
275 | ||
8329bd07 PB |
276 | proc populate_remotes_menu {} { |
277 | global all_remotes | |
278 | ||
279 | foreach r $all_remotes { | |
280 | add_fetch_entry $r | |
281 | add_push_entry $r | |
f522c9b5 | 282 | } |
69e21b83 HV |
283 | |
284 | update_all_remotes_menu_entry | |
f522c9b5 | 285 | } |
ba6485e0 PB |
286 | |
287 | proc add_single_remote {name location} { | |
288 | global all_remotes repo_config | |
289 | lappend all_remotes $name | |
290 | ||
291 | git remote add $name $location | |
292 | ||
293 | # XXX: Better re-read the config so that we will never get out | |
294 | # of sync with git remote implementation? | |
295 | set repo_config(remote.$name.url) $location | |
296 | set repo_config(remote.$name.fetch) "+refs/heads/*:refs/remotes/$name/*" | |
297 | ||
298 | add_fetch_entry $name | |
299 | add_push_entry $name | |
69e21b83 HV |
300 | |
301 | update_all_remotes_menu_entry | |
ba6485e0 | 302 | } |
0d404412 PB |
303 | |
304 | proc delete_from_menu {menu name} { | |
305 | if {[winfo exists $menu]} { | |
306 | $menu delete $name | |
307 | } | |
308 | } | |
309 | ||
310 | proc remove_remote {name} { | |
311 | global all_remotes repo_config | |
312 | ||
313 | git remote rm $name | |
314 | ||
315 | catch { | |
316 | # Missing values are ok | |
317 | unset repo_config(remote.$name.url) | |
318 | unset repo_config(remote.$name.fetch) | |
319 | unset repo_config(remote.$name.push) | |
320 | } | |
321 | ||
8b926582 HV |
322 | set i [lsearch -exact $all_remotes $name] |
323 | set all_remotes [lreplace $all_remotes $i $i] | |
0d404412 PB |
324 | |
325 | set remote_m .mbar.remote | |
326 | delete_from_menu $remote_m.fetch $name | |
327 | delete_from_menu $remote_m.prune $name | |
328 | delete_from_menu $remote_m.remove $name | |
2243ffcc PB |
329 | # Not all remotes are in the push menu |
330 | catch { delete_from_menu $remote_m.push $name } | |
69e21b83 HV |
331 | |
332 | update_all_remotes_menu_entry | |
0d404412 | 333 | } |