lib / remote.tclon commit git-gui: Always use absolute path to all git executables (0b81261)
   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 [list]
  21        set pat [list]
  22        set cmd [list]
  23
  24        foreach spec $tracking_branches {
  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]
  29                } else {
  30                        lappend all $spec
  31                }
  32        }
  33
  34        if {$pat ne {}} {
  35                set fd [eval git_read for-each-ref --format=%(refname) $cmd]
  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                        }
  50                }
  51                close $fd
  52        }
  53
  54        return [lsort -index 0 -unique $all]
  55}
  56
  57proc load_all_remotes {} {
  58        global repo_config
  59        global all_remotes tracking_branches some_heads_tracking
  60
  61        set some_heads_tracking 0
  62        set all_remotes [list]
  63        set trck [list]
  64
  65        set rh_str refs/heads/
  66        set rh_len [string length $rh_str]
  67        set rm_dir [gitdir remotes]
  68        if {[file isdirectory $rm_dir]} {
  69                set all_remotes [glob \
  70                        -types f \
  71                        -tails \
  72                        -nocomplain \
  73                        -directory $rm_dir *]
  74
  75                foreach name $all_remotes {
  76                        catch {
  77                                set fd [open [file join $rm_dir $name] r]
  78                                while {[gets $fd line] >= 0} {
  79                                        if {![regexp {^Pull:[   ]*([^:]+):(.+)$} \
  80                                                $line line src dst]} continue
  81                                        if {[string index $src 0] eq {+}} {
  82                                                set src [string range $src 1 end]
  83                                        }
  84                                        if {![string equal -length 5 refs/ $src]} {
  85                                                set src $rh_str$src
  86                                        }
  87                                        if {![string equal -length 5 refs/ $dst]} {
  88                                                set dst $rh_str$dst
  89                                        }
  90                                        if {[string equal -length $rh_len $rh_str $dst]} {
  91                                                set some_heads_tracking 1
  92                                        }
  93                                        lappend trck [list $dst $name $src]
  94                                }
  95                                close $fd
  96                        }
  97                }
  98        }
  99
 100        foreach line [array names repo_config remote.*.url] {
 101                if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue
 102                lappend all_remotes $name
 103
 104                if {[catch {set fl $repo_config(remote.$name.fetch)}]} {
 105                        set fl {}
 106                }
 107                foreach line $fl {
 108                        if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue
 109                        if {[string index $src 0] eq {+}} {
 110                                set src [string range $src 1 end]
 111                        }
 112                        if {![string equal -length 5 refs/ $src]} {
 113                                set src $rh_str$src
 114                        }
 115                        if {![string equal -length 5 refs/ $dst]} {
 116                                set dst $rh_str$dst
 117                        }
 118                        if {[string equal -length $rh_len $rh_str $dst]} {
 119                                set some_heads_tracking 1
 120                        }
 121                        lappend trck [list $dst $name $src]
 122                }
 123        }
 124
 125        set tracking_branches [lsort -index 0 -unique $trck]
 126        set all_remotes [lsort -unique $all_remotes]
 127}
 128
 129proc populate_fetch_menu {} {
 130        global all_remotes repo_config
 131
 132        set m .mbar.fetch
 133        set prune_list [list]
 134        foreach r $all_remotes {
 135                set enable 0
 136                if {![catch {set a $repo_config(remote.$r.url)}]} {
 137                        if {![catch {set a $repo_config(remote.$r.fetch)}]} {
 138                                set enable 1
 139                        }
 140                } else {
 141                        catch {
 142                                set fd [open [gitdir remotes $r] r]
 143                                while {[gets $fd n] >= 0} {
 144                                        if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
 145                                                set enable 1
 146                                                break
 147                                        }
 148                                }
 149                                close $fd
 150                        }
 151                }
 152
 153                if {$enable} {
 154                        lappend prune_list $r
 155                        $m add command \
 156                                -label "Fetch from $r..." \
 157                                -command [list fetch_from $r]
 158                }
 159        }
 160
 161        if {$prune_list ne {}} {
 162                $m add separator
 163        }
 164        foreach r $prune_list {
 165                $m add command \
 166                        -label "Prune from $r..." \
 167                        -command [list prune_from $r]
 168        }
 169}
 170
 171proc populate_push_menu {} {
 172        global all_remotes repo_config
 173
 174        set m .mbar.push
 175        set fast_count 0
 176        foreach r $all_remotes {
 177                set enable 0
 178                if {![catch {set a $repo_config(remote.$r.url)}]} {
 179                        if {![catch {set a $repo_config(remote.$r.push)}]} {
 180                                set enable 1
 181                        }
 182                } else {
 183                        catch {
 184                                set fd [open [gitdir remotes $r] r]
 185                                while {[gets $fd n] >= 0} {
 186                                        if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
 187                                                set enable 1
 188                                                break
 189                                        }
 190                                }
 191                                close $fd
 192                        }
 193                }
 194
 195                if {$enable} {
 196                        if {!$fast_count} {
 197                                $m add separator
 198                        }
 199                        $m add command \
 200                                -label "Push to $r..." \
 201                                -command [list push_to $r]
 202                        incr fast_count
 203                }
 204        }
 205}