git-gui / lib / remote_add.tclon commit push: fix segfault for odd config (db03b55)
   1# git-gui remote adding support
   2# Copyright (C) 2008 Petr Baudis
   3
   4class remote_add {
   5
   6field w              ; # widget path
   7field w_name         ; # new remote name widget
   8field w_loc          ; # new remote location widget
   9
  10field name         {}; # name of the remote the user has chosen
  11field location     {}; # location of the remote the user has chosen
  12
  13field opt_action fetch; # action to do after registering the remote locally
  14
  15constructor dialog {} {
  16        global repo_config
  17
  18        make_toplevel top w
  19        wm title $top [append "[appname] ([reponame]): " [mc "Add Remote"]]
  20        if {$top ne {.}} {
  21                wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
  22        }
  23
  24        label $w.header -text [mc "Add New Remote"] -font font_uibold
  25        pack $w.header -side top -fill x
  26
  27        frame $w.buttons
  28        button $w.buttons.create -text [mc Add] \
  29                -default active \
  30                -command [cb _add]
  31        pack $w.buttons.create -side right
  32        button $w.buttons.cancel -text [mc Cancel] \
  33                -command [list destroy $w]
  34        pack $w.buttons.cancel -side right -padx 5
  35        pack $w.buttons -side bottom -fill x -pady 10 -padx 10
  36
  37        labelframe $w.desc -text [mc "Remote Details"]
  38
  39        label $w.desc.name_l -text [mc "Name:"]
  40        set w_name $w.desc.name_t
  41        entry $w_name \
  42                -borderwidth 1 \
  43                -relief sunken \
  44                -width 40 \
  45                -textvariable @name \
  46                -validate key \
  47                -validatecommand [cb _validate_name %d %S]
  48        grid $w.desc.name_l $w_name -sticky we -padx {0 5}
  49
  50        label $w.desc.loc_l -text [mc "Location:"]
  51        set w_loc $w.desc.loc_t
  52        entry $w_loc \
  53                -borderwidth 1 \
  54                -relief sunken \
  55                -width 40 \
  56                -textvariable @location
  57        grid $w.desc.loc_l $w_loc -sticky we -padx {0 5}
  58
  59        grid columnconfigure $w.desc 1 -weight 1
  60        pack $w.desc -anchor nw -fill x -pady 5 -padx 5
  61
  62        labelframe $w.action -text [mc "Further Action"]
  63
  64        radiobutton $w.action.fetch \
  65                -text [mc "Fetch Immediately"] \
  66                -value fetch \
  67                -variable @opt_action
  68        pack $w.action.fetch -anchor nw
  69
  70        radiobutton $w.action.push \
  71                -text [mc "Initialize Remote Repository and Push"] \
  72                -value push \
  73                -variable @opt_action
  74        pack $w.action.push -anchor nw
  75
  76        radiobutton $w.action.none \
  77                -text [mc "Do Nothing Else Now"] \
  78                -value none \
  79                -variable @opt_action
  80        pack $w.action.none -anchor nw
  81
  82        grid columnconfigure $w.action 1 -weight 1
  83        pack $w.action -anchor nw -fill x -pady 5 -padx 5
  84
  85        bind $w <Visibility> [cb _visible]
  86        bind $w <Key-Escape> [list destroy $w]
  87        bind $w <Key-Return> [cb _add]\;break
  88        tkwait window $w
  89}
  90
  91method _add {} {
  92        global repo_config env
  93        global M1B
  94
  95        if {$name eq {}} {
  96                tk_messageBox \
  97                        -icon error \
  98                        -type ok \
  99                        -title [wm title $w] \
 100                        -parent $w \
 101                        -message [mc "Please supply a remote name."]
 102                focus $w_name
 103                return
 104        }
 105
 106        # XXX: We abuse check-ref-format here, but
 107        # that should be ok.
 108        if {[catch {git check-ref-format "remotes/$name"}]} {
 109                tk_messageBox \
 110                        -icon error \
 111                        -type ok \
 112                        -title [wm title $w] \
 113                        -parent $w \
 114                        -message [mc "'%s' is not an acceptable remote name." $name]
 115                focus $w_name
 116                return
 117        }
 118
 119        if {[catch {add_single_remote $name $location}]} {
 120                tk_messageBox \
 121                        -icon error \
 122                        -type ok \
 123                        -title [wm title $w] \
 124                        -parent $w \
 125                        -message [mc "Failed to add remote '%s' of location '%s'." $name $location]
 126                focus $w_name
 127                return
 128        }
 129
 130        switch -- $opt_action {
 131        fetch {
 132                set c [console::new \
 133                        [mc "fetch %s" $name] \
 134                        [mc "Fetching the %s" $name]]
 135                console::exec $c [list git fetch $name]
 136        }
 137        push {
 138                set cmds [list]
 139
 140                # Parse the location
 141                if { [regexp {(?:git\+)?ssh://([^/]+)(/.+)} $location xx host path]
 142                     || [regexp {([^:][^:]+):(.+)} $location xx host path]} {
 143                        set ssh ssh
 144                        if {[info exists env(GIT_SSH)]} {
 145                                set ssh $env(GIT_SSH)
 146                        }
 147                        lappend cmds [list exec $ssh $host mkdir -p $location && git --git-dir=$path init --bare]
 148                } elseif { ! [regexp {://} $location xx] } {
 149                        lappend cmds [list exec mkdir -p $location]
 150                        lappend cmds [list exec git --git-dir=$location init --bare]
 151                } else {
 152                        tk_messageBox \
 153                                -icon error \
 154                                -type ok \
 155                                -title [wm title $w] \
 156                                -parent $w \
 157                                -message [mc "Do not know how to initialize repository at location '%s'." $location]
 158                        destroy $w
 159                        return
 160                }
 161
 162                set c [console::new \
 163                        [mc "push %s" $name] \
 164                        [mc "Setting up the %s (at %s)" $name $location]]
 165
 166                lappend cmds [list exec git push -v --all $name]
 167                console::chain $c $cmds
 168        }
 169        none {
 170        }
 171        }
 172
 173        destroy $w
 174}
 175
 176method _validate_name {d S} {
 177        if {$d == 1} {
 178                if {[regexp {[~^:?*\[\0- ]} $S]} {
 179                        return 0
 180                }
 181        }
 182        return 1
 183}
 184
 185method _visible {} {
 186        grab $w
 187        $w_name icursor end
 188        focus $w_name
 189}
 190
 191}