55a6dc33011701902f12c9af575074808bbcbcba
   1# git-gui remote management
   2# Copyright (C) 2006, 2007 Shawn Pearce
   3
   4set some_heads_tracking 0;  # assume not
   5
   6proc 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
  17proc 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
  44proc 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
 110proc 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
 152proc 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}