Merge branch 'mg/maint-send-email-lazy-editor' into maint
[git] / git-gui / lib / branch_create.tcl
1 # git-gui branch create support
2 # Copyright (C) 2006, 2007 Shawn Pearce
3
4 class branch_create {
5
6 field w              ; # widget path
7 field w_rev          ; # mega-widget to pick the initial revision
8 field w_name         ; # new branch name widget
9
10 field name         {}; # name of the branch the user has chosen
11 field name_type  user; # type of branch name to use
12
13 field opt_merge    ff; # type of merge to apply to existing branch
14 field opt_checkout  1; # automatically checkout the new branch?
15 field opt_fetch     1; # refetch tracking branch if used?
16 field reset_ok      0; # did the user agree to reset?
17
18 constructor dialog {} {
19         global repo_config use_ttk NS
20
21         make_dialog top w
22         wm withdraw $w
23         wm title $top [append "[appname] ([reponame]): " [mc "Create Branch"]]
24         if {$top ne {.}} {
25                 wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
26         }
27
28         ${NS}::label $w.header -text [mc "Create New Branch"] \
29                 -font font_uibold -anchor center
30         pack $w.header -side top -fill x
31
32         ${NS}::frame $w.buttons
33         ${NS}::button $w.buttons.create -text [mc Create] \
34                 -default active \
35                 -command [cb _create]
36         pack $w.buttons.create -side right
37         ${NS}::button $w.buttons.cancel -text [mc Cancel] \
38                 -command [list destroy $w]
39         pack $w.buttons.cancel -side right -padx 5
40         pack $w.buttons -side bottom -fill x -pady 10 -padx 10
41
42         ${NS}::labelframe $w.desc -text [mc "Branch Name"]
43         ${NS}::radiobutton $w.desc.name_r \
44                 -text [mc "Name:"] \
45                 -value user \
46                 -variable @name_type
47         if {!$use_ttk} {$w.desc.name_r configure -anchor w}
48         set w_name $w.desc.name_t
49         ${NS}::entry $w_name \
50                 -width 40 \
51                 -textvariable @name \
52                 -validate key \
53                 -validatecommand [cb _validate %d %S]
54         grid $w.desc.name_r $w_name -sticky we -padx {0 5}
55
56         ${NS}::radiobutton $w.desc.match_r \
57                 -text [mc "Match Tracking Branch Name"] \
58                 -value match \
59                 -variable @name_type
60         if {!$use_ttk} {$w.desc.match_r configure -anchor w}
61         grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2
62
63         grid columnconfigure $w.desc 1 -weight 1
64         pack $w.desc -anchor nw -fill x -pady 5 -padx 5
65
66         set w_rev [::choose_rev::new $w.rev [mc "Starting Revision"]]
67         pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
68
69         ${NS}::labelframe $w.options -text [mc Options]
70
71         ${NS}::frame $w.options.merge
72         ${NS}::label $w.options.merge.l -text [mc "Update Existing Branch:"]
73         pack $w.options.merge.l -side left
74         ${NS}::radiobutton $w.options.merge.no \
75                 -text [mc No] \
76                 -value none \
77                 -variable @opt_merge
78         pack $w.options.merge.no -side left
79         ${NS}::radiobutton $w.options.merge.ff \
80                 -text [mc "Fast Forward Only"] \
81                 -value ff \
82                 -variable @opt_merge
83         pack $w.options.merge.ff -side left
84         ${NS}::radiobutton $w.options.merge.reset \
85                 -text [mc Reset] \
86                 -value reset \
87                 -variable @opt_merge
88         pack $w.options.merge.reset -side left
89         pack $w.options.merge -anchor nw
90
91         ${NS}::checkbutton $w.options.fetch \
92                 -text [mc "Fetch Tracking Branch"] \
93                 -variable @opt_fetch
94         pack $w.options.fetch -anchor nw
95
96         ${NS}::checkbutton $w.options.checkout \
97                 -text [mc "Checkout After Creation"] \
98                 -variable @opt_checkout
99         pack $w.options.checkout -anchor nw
100         pack $w.options -anchor nw -fill x -pady 5 -padx 5
101
102         trace add variable @name_type write [cb _select]
103
104         set name $repo_config(gui.newbranchtemplate)
105         if {[is_config_true gui.matchtrackingbranch]} {
106                 set name_type match
107         }
108
109         bind $w <Visibility> [cb _visible]
110         bind $w <Key-Escape> [list destroy $w]
111         bind $w <Key-Return> [cb _create]\;break
112         wm deiconify $w
113         tkwait window $w
114 }
115
116 method _create {} {
117         global repo_config
118         global M1B
119
120         set spec [$w_rev get_tracking_branch]
121         switch -- $name_type {
122         user {
123                 set newbranch $name
124         }
125         match {
126                 if {$spec eq {}} {
127                         tk_messageBox \
128                                 -icon error \
129                                 -type ok \
130                                 -title [wm title $w] \
131                                 -parent $w \
132                                 -message [mc "Please select a tracking branch."]
133                         return
134                 }
135                 if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
136                         tk_messageBox \
137                                 -icon error \
138                                 -type ok \
139                                 -title [wm title $w] \
140                                 -parent $w \
141                                 -message [mc "Tracking branch %s is not a branch in the remote repository." [$w get]]
142                         return
143                 }
144         }
145         }
146
147         if {$newbranch eq {}
148                 || $newbranch eq $repo_config(gui.newbranchtemplate)} {
149                 tk_messageBox \
150                         -icon error \
151                         -type ok \
152                         -title [wm title $w] \
153                         -parent $w \
154                         -message [mc "Please supply a branch name."]
155                 focus $w_name
156                 return
157         }
158
159         if {[catch {git check-ref-format "heads/$newbranch"}]} {
160                 tk_messageBox \
161                         -icon error \
162                         -type ok \
163                         -title [wm title $w] \
164                         -parent $w \
165                         -message [mc "'%s' is not an acceptable branch name." $newbranch]
166                 focus $w_name
167                 return
168         }
169
170         if {$spec ne {} && $opt_fetch} {
171                 set new {}
172         } elseif {[catch {set new [$w_rev commit_or_die]}]} {
173                 return
174         }
175
176         set co [::checkout_op::new \
177                 [$w_rev get] \
178                 $new \
179                 refs/heads/$newbranch]
180         $co parent $w
181         $co enable_create   1
182         $co enable_merge    $opt_merge
183         $co enable_checkout $opt_checkout
184         if {$spec ne {} && $opt_fetch} {
185                 $co enable_fetch $spec
186         }
187         if {$spec ne {}} {
188                 $co remote_source $spec
189         }
190
191         if {[$co run]} {
192                 destroy $w
193         } else {
194                 focus $w_name
195         }
196 }
197
198 method _validate {d S} {
199         if {$d == 1} {
200                 if {[regexp {[~^:?*\[\0- ]} $S]} {
201                         return 0
202                 }
203                 if {[string length $S] > 0} {
204                         set name_type user
205                 }
206         }
207         return 1
208 }
209
210 method _select {args} {
211         if {$name_type eq {match}} {
212                 $w_rev pick_tracking_branch
213         }
214 }
215
216 method _visible {} {
217         grab $w
218         if {$name_type eq {user}} {
219                 $w_name icursor end
220                 focus $w_name
221         }
222 }
223
224 }