@matheusbsbs / matheus-bagliano / commits / ba6485e05d
Fork 0

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 +}