git-gui / lib / remote.tclon commit Merge branch 'master' of git://repo.or.cz/git-gui (5f5dbd7)
   1# git-gui remote management
   2# Copyright (C) 2006, 2007 Shawn Pearce
   3
   4proc is_tracking_branch {name} {
   5        global tracking_branches
   6
   7        if {![catch {set info $tracking_branches($name)}]} {
   8                return 1
   9        }
  10        foreach t [array names tracking_branches] {
  11                if {[string match {*/\*} $t] && [string match $t $name]} {
  12                        return 1
  13                }
  14        }
  15        return 0
  16}
  17
  18proc all_tracking_branches {} {
  19        global tracking_branches
  20
  21        set all_trackings {}
  22        set cmd {}
  23        foreach name [array names tracking_branches] {
  24                if {[regsub {/\*$} $name {} name]} {
  25                        lappend cmd $name
  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
  47
  48        set all_remotes [list]
  49        array unset tracking_branches
  50
  51        set rm_dir [gitdir remotes]
  52        if {[file isdirectory $rm_dir]} {
  53                set all_remotes [glob \
  54                        -types f \
  55                        -tails \
  56                        -nocomplain \
  57                        -directory $rm_dir *]
  58
  59                foreach name $all_remotes {
  60                        catch {
  61                                set fd [open [file join $rm_dir $name] r]
  62                                while {[gets $fd line] >= 0} {
  63                                        if {![regexp {^Pull:[   ]*([^:]+):(.+)$} \
  64                                                $line line src dst]} continue
  65                                        if {![regexp ^refs/ $dst]} {
  66                                                set dst "refs/heads/$dst"
  67                                        }
  68                                        set tracking_branches($dst) [list $name $src]
  69                                }
  70                                close $fd
  71                        }
  72                }
  73        }
  74
  75        foreach line [array names repo_config remote.*.url] {
  76                if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue
  77                lappend all_remotes $name
  78
  79                if {[catch {set fl $repo_config(remote.$name.fetch)}]} {
  80                        set fl {}
  81                }
  82                foreach line $fl {
  83                        if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue
  84                        if {![regexp ^refs/ $dst]} {
  85                                set dst "refs/heads/$dst"
  86                        }
  87                        set tracking_branches($dst) [list $name $src]
  88                }
  89        }
  90
  91        set all_remotes [lsort -unique $all_remotes]
  92}
  93
  94proc populate_fetch_menu {} {
  95        global all_remotes repo_config
  96
  97        set m .mbar.fetch
  98        foreach r $all_remotes {
  99                set enable 0
 100                if {![catch {set a $repo_config(remote.$r.url)}]} {
 101                        if {![catch {set a $repo_config(remote.$r.fetch)}]} {
 102                                set enable 1
 103                        }
 104                } else {
 105                        catch {
 106                                set fd [open [gitdir remotes $r] r]
 107                                while {[gets $fd n] >= 0} {
 108                                        if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
 109                                                set enable 1
 110                                                break
 111                                        }
 112                                }
 113                                close $fd
 114                        }
 115                }
 116
 117                if {$enable} {
 118                        $m add command \
 119                                -label "Fetch from $r..." \
 120                                -command [list fetch_from $r]
 121                }
 122        }
 123}
 124
 125proc populate_push_menu {} {
 126        global all_remotes repo_config
 127
 128        set m .mbar.push
 129        set fast_count 0
 130        foreach r $all_remotes {
 131                set enable 0
 132                if {![catch {set a $repo_config(remote.$r.url)}]} {
 133                        if {![catch {set a $repo_config(remote.$r.push)}]} {
 134                                set enable 1
 135                        }
 136                } else {
 137                        catch {
 138                                set fd [open [gitdir remotes $r] r]
 139                                while {[gets $fd n] >= 0} {
 140                                        if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
 141                                                set enable 1
 142                                                break
 143                                        }
 144                                }
 145                                close $fd
 146                        }
 147                }
 148
 149                if {$enable} {
 150                        if {!$fast_count} {
 151                                $m add separator
 152                        }
 153                        $m add command \
 154                                -label "Push to $r..." \
 155                                -command [list push_to $r]
 156                        incr fast_count
 157                }
 158        }
 159}