Spaces:
Runtime error
Runtime error
| # git-gui remote management | |
| # Copyright (C) 2006, 2007 Shawn Pearce | |
| set some_heads_tracking 0; # assume not | |
| proc is_tracking_branch {name} { | |
| global tracking_branches | |
| foreach spec $tracking_branches { | |
| set t [lindex $spec 0] | |
| if {$t eq $name || [string match $t $name]} { | |
| return 1 | |
| } | |
| } | |
| return 0 | |
| } | |
| proc all_tracking_branches {} { | |
| global tracking_branches | |
| set all [list] | |
| set pat [list] | |
| set cmd [list] | |
| foreach spec $tracking_branches { | |
| 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 { | |
| lappend all $spec | |
| } | |
| } | |
| if {$pat ne {}} { | |
| set fd [eval git_read for-each-ref --format=%(refname) $cmd] | |
| 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 -index 0 -unique $all] | |
| } | |
| proc load_all_remotes {} { | |
| global repo_config | |
| global all_remotes tracking_branches some_heads_tracking | |
| global remote_url | |
| set some_heads_tracking 0 | |
| set all_remotes [list] | |
| set trck [list] | |
| set rh_str refs/heads/ | |
| set rh_len [string length $rh_str] | |
| set rm_dir [gitdir remotes] | |
| if {[file isdirectory $rm_dir]} { | |
| set all_remotes [glob \ | |
| -types f \ | |
| -tails \ | |
| -nocomplain \ | |
| -directory $rm_dir *] | |
| foreach name $all_remotes { | |
| catch { | |
| set fd [open [file join $rm_dir $name] r] | |
| while {[gets $fd line] >= 0} { | |
| if {[regexp {^URL:[ ]*(.+)$} $line line url]} { | |
| set remote_url($name) $url | |
| continue | |
| } | |
| 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 | |
| } | |
| if {![string equal -length 5 refs/ $dst]} { | |
| set dst $rh_str$dst | |
| } | |
| if {[string equal -length $rh_len $rh_str $dst]} { | |
| set some_heads_tracking 1 | |
| } | |
| lappend trck [list $dst $name $src] | |
| } | |
| close $fd | |
| } | |
| } | |
| } | |
| foreach line [array names repo_config remote.*.url] { | |
| if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue | |
| lappend all_remotes $name | |
| set remote_url($name) $repo_config(remote.$name.url) | |
| if {[catch {set fl $repo_config(remote.$name.fetch)}]} { | |
| set fl {} | |
| } | |
| 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 | |
| } | |
| if {![string equal -length 5 refs/ $dst]} { | |
| set dst $rh_str$dst | |
| } | |
| if {[string equal -length $rh_len $rh_str $dst]} { | |
| set some_heads_tracking 1 | |
| } | |
| lappend trck [list $dst $name $src] | |
| } | |
| } | |
| set tracking_branches [lsort -index 0 -unique $trck] | |
| set all_remotes [lsort -unique $all_remotes] | |
| } | |
| proc add_fetch_entry {r} { | |
| global repo_config | |
| set remote_m .mbar.remote | |
| set fetch_m $remote_m.fetch | |
| set prune_m $remote_m.prune | |
| set remove_m $remote_m.remove | |
| set enable 0 | |
| if {![catch {set a $repo_config(remote.$r.url)}]} { | |
| if {![catch {set a $repo_config(remote.$r.fetch)}]} { | |
| set enable 1 | |
| } | |
| } else { | |
| catch { | |
| set fd [open [gitdir remotes $r] r] | |
| while {[gets $fd n] >= 0} { | |
| if {[regexp {^Pull:[ \t]*([^:]+):} $n]} { | |
| set enable 1 | |
| break | |
| } | |
| } | |
| close $fd | |
| } | |
| } | |
| if {$enable} { | |
| make_sure_remote_submenues_exist $remote_m | |
| $fetch_m add command \ | |
| -label $r \ | |
| -command [list fetch_from $r] | |
| $prune_m add command \ | |
| -label $r \ | |
| -command [list prune_from $r] | |
| $remove_m add command \ | |
| -label $r \ | |
| -command [list remove_remote $r] | |
| } | |
| } | |
| proc add_push_entry {r} { | |
| global repo_config | |
| set remote_m .mbar.remote | |
| set push_m $remote_m.push | |
| set enable 0 | |
| if {![catch {set a $repo_config(remote.$r.url)}]} { | |
| if {![catch {set a $repo_config(remote.$r.push)}]} { | |
| set enable 1 | |
| } | |
| } else { | |
| catch { | |
| set fd [open [gitdir remotes $r] r] | |
| while {[gets $fd n] >= 0} { | |
| if {[regexp {^Push:[ \t]*([^:]+):} $n]} { | |
| set enable 1 | |
| break | |
| } | |
| } | |
| close $fd | |
| } | |
| } | |
| if {$enable} { | |
| if {![winfo exists $push_m]} { | |
| menu $push_m | |
| $remote_m insert 0 cascade \ | |
| -label [mc "Push to"] \ | |
| -menu $push_m | |
| } | |
| $push_m add command \ | |
| -label $r \ | |
| -command [list push_to $r] | |
| } | |
| } | |
| proc make_sure_remote_submenues_exist {remote_m} { | |
| set fetch_m $remote_m.fetch | |
| set prune_m $remote_m.prune | |
| set remove_m $remote_m.remove | |
| if {![winfo exists $fetch_m]} { | |
| menu $remove_m | |
| $remote_m insert 0 cascade \ | |
| -label [mc "Remove Remote"] \ | |
| -menu $remove_m | |
| menu $prune_m | |
| $remote_m insert 0 cascade \ | |
| -label [mc "Prune from"] \ | |
| -menu $prune_m | |
| menu $fetch_m | |
| $remote_m insert 0 cascade \ | |
| -label [mc "Fetch from"] \ | |
| -menu $fetch_m | |
| } | |
| } | |
| proc update_all_remotes_menu_entry {} { | |
| global all_remotes | |
| if {[git-version < 1.6.6]} { return } | |
| set have_remote 0 | |
| foreach r $all_remotes { | |
| incr have_remote | |
| } | |
| set remote_m .mbar.remote | |
| set fetch_m $remote_m.fetch | |
| set prune_m $remote_m.prune | |
| if {$have_remote > 1} { | |
| make_sure_remote_submenues_exist $remote_m | |
| if {[$fetch_m type end] eq "command" \ | |
| && [$fetch_m entrycget end -label] ne [mc "All"]} { | |
| $fetch_m insert end separator | |
| $fetch_m insert end command \ | |
| -label [mc "All"] \ | |
| -command fetch_from_all | |
| $prune_m insert end separator | |
| $prune_m insert end command \ | |
| -label [mc "All"] \ | |
| -command prune_from_all | |
| } | |
| } else { | |
| if {[winfo exists $fetch_m]} { | |
| if {[$fetch_m type end] eq "command" \ | |
| && [$fetch_m entrycget end -label] eq [mc "All"]} { | |
| delete_from_menu $fetch_m end | |
| delete_from_menu $fetch_m end | |
| delete_from_menu $prune_m end | |
| delete_from_menu $prune_m end | |
| } | |
| } | |
| } | |
| } | |
| proc populate_remotes_menu {} { | |
| global all_remotes | |
| foreach r $all_remotes { | |
| add_fetch_entry $r | |
| add_push_entry $r | |
| } | |
| update_all_remotes_menu_entry | |
| } | |
| proc add_single_remote {name location} { | |
| global all_remotes repo_config | |
| lappend all_remotes $name | |
| git remote add $name $location | |
| # XXX: Better re-read the config so that we will never get out | |
| # of sync with git remote implementation? | |
| set repo_config(remote.$name.url) $location | |
| set repo_config(remote.$name.fetch) "+refs/heads/*:refs/remotes/$name/*" | |
| add_fetch_entry $name | |
| add_push_entry $name | |
| update_all_remotes_menu_entry | |
| } | |
| proc delete_from_menu {menu name} { | |
| if {[winfo exists $menu]} { | |
| $menu delete $name | |
| } | |
| } | |
| proc remove_remote {name} { | |
| global all_remotes repo_config | |
| git remote rm $name | |
| catch { | |
| # Missing values are ok | |
| unset repo_config(remote.$name.url) | |
| unset repo_config(remote.$name.fetch) | |
| unset repo_config(remote.$name.push) | |
| } | |
| set i [lsearch -exact $all_remotes $name] | |
| set all_remotes [lreplace $all_remotes $i $i] | |
| set remote_m .mbar.remote | |
| delete_from_menu $remote_m.fetch $name | |
| delete_from_menu $remote_m.prune $name | |
| delete_from_menu $remote_m.remove $name | |
| # Not all remotes are in the push menu | |
| catch { delete_from_menu $remote_m.push $name } | |
| update_all_remotes_menu_entry | |
| } | |