git-gui: Add support for adding remotes
When a remote is being added, it can also be automatically either fetched or initialized and pushed; this patch adds capability for initializing of local and ssh repositories. This also of course leaves a lot of space for further customization features, like individually turning the initialization phase on/off or tuning attributes of the remote repository; I consider that out of scope of this patch, however. Signed-off-by: Petr Baudis <petr.baudis@novartis.com> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Petr Baudis committed
Sep 24, 2008 at 22:44 UTC
ba6485e05d43abf66e6b651a41b1ddc511b0e5eb
3 files changed
+209
git-gui.sh
+4
@@ -2448,6 +2448,10 @@ if {[is_enabled branch]} {
2448
if {[is_enabled transport]} {
2449
menu .mbar.remote
2450
2451
+ .mbar.remote add command \
2452
+ -label [mc "Add..."] \
2453
+ -command remote_add::dialog \
2454
+ -accelerator $M1T-A
2455
.mbar.remote add command \
2456
-label [mc "Push..."] \
2457
-command do_push_anywhere \
lib/remote.tcl
+15
@@ -221,3 +221,18 @@ proc populate_remotes_menu {} {
221
add_push_entry $r
222
}
223
}
224
+
225
+proc add_single_remote {name location} {
226
+ global all_remotes repo_config
227
+ lappend all_remotes $name
228
+
229
+ git remote add $name $location
230
+
231
+ # XXX: Better re-read the config so that we will never get out
232
+ # of sync with git remote implementation?
233
+ set repo_config(remote.$name.url) $location
234
+ set repo_config(remote.$name.fetch) "+refs/heads/*:refs/remotes/$name/*"
235
+
236
+ add_fetch_entry $name
237
+ add_push_entry $name
238
+}
lib/remote_add.tcl
new
+190
@@ -0,0 +1,190 @@
1
+# git-gui remote adding support
2
+# Copyright (C) 2008 Petr Baudis
3
+
4
+class remote_add {
5
+
6
+field w ; # widget path
7
+field w_name ; # new remote name widget
8
+field w_loc ; # new remote location widget
9
+
10
+field name {}; # name of the remote the user has chosen
11
+field location {}; # location of the remote the user has chosen
12
+
13
+field opt_action fetch; # action to do after registering the remote locally
14
+
15
+constructor 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
+
91
+method _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" $remote] \
134
+ [mc "Fetching the %s" $remote]]
135
+ console::exec $c [list git fetch --all $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 git --git-dir=$path init --bare]
148
+ } elseif { ! [regexp {://} $location xx] } {
149
+ lappend cmds [list exec git --git-dir=$location init --bare]
150
+ } else {
151
+ tk_messageBox \
152
+ -icon error \
153
+ -type ok \
154
+ -title [wm title $w] \
155
+ -parent $w \
156
+ -message [mc "Do not know how to initialize repository at location '%s'." $location]
157
+ destroy $w
158
+ return
159
+ }
160
+
161
+ set c [console::new \
162
+ [mc "push %s" $name] \
163
+ [mc "Setting up the %s (at %s)" $name $location]]
164
+
165
+ lappend cmds [list exec git push -v --all $name]
166
+ console::chain $c $cmds
167
+ }
168
+ none {
169
+ }
170
+ }
171
+
172
+ destroy $w
173
+}
174
+
175
+method _validate_name {d S} {
176
+ if {$d == 1} {
177
+ if {[regexp {[~^:?*\[\0- ]} $S]} {
178
+ return 0
179
+ }
180
+ }
181
+ return 1
182
+}
183
+
184
+method _visible {} {
185
+ grab $w
186
+ $w_name icursor end
187
+ focus $w_name
188
+}
189
+
190
+}