]>
Commit | Line | Data |
---|---|---|
f522c9b5 SP |
1 | # git-gui index (add/remove) support |
2 | # Copyright (C) 2006, 2007 Shawn Pearce | |
3 | ||
d4e890e5 SP |
4 | proc _delete_indexlock {} { |
5 | if {[catch {file delete -- [gitdir index.lock]} err]} { | |
6 | error_popup [strcat [mc "Unable to unlock the index."] "\n\n$err"] | |
7 | } | |
8 | } | |
9 | ||
10 | proc _close_updateindex {fd after} { | |
c80d7be5 | 11 | global use_ttk NS |
d4e890e5 SP |
12 | fconfigure $fd -blocking 1 |
13 | if {[catch {close $fd} err]} { | |
14 | set w .indexfried | |
c80d7be5 PT |
15 | Dialog $w |
16 | wm withdraw $w | |
d4e890e5 SP |
17 | wm title $w [strcat "[appname] ([reponame]): " [mc "Index Error"]] |
18 | wm geometry $w "+[winfo rootx .]+[winfo rooty .]" | |
ea888f84 PT |
19 | set s [mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] |
20 | text $w.msg -yscrollcommand [list $w.vs set] \ | |
21 | -width [string length $s] -relief flat \ | |
22 | -borderwidth 0 -highlightthickness 0 \ | |
c80d7be5 | 23 | -background [get_bg_color $w] |
ea888f84 | 24 | $w.msg tag configure bold -font font_uibold -justify center |
c80d7be5 | 25 | ${NS}::scrollbar $w.vs -command [list $w.msg yview] |
ea888f84 PT |
26 | $w.msg insert end $s bold \n\n$err {} |
27 | $w.msg configure -state disabled | |
28 | ||
c80d7be5 | 29 | ${NS}::button $w.continue \ |
d4e890e5 SP |
30 | -text [mc "Continue"] \ |
31 | -command [list destroy $w] | |
c80d7be5 | 32 | ${NS}::button $w.unlock \ |
d4e890e5 SP |
33 | -text [mc "Unlock Index"] \ |
34 | -command "destroy $w; _delete_indexlock" | |
ea888f84 PT |
35 | grid $w.msg - $w.vs -sticky news |
36 | grid $w.unlock $w.continue - -sticky se -padx 2 -pady 2 | |
37 | grid columnconfigure $w 0 -weight 1 | |
38 | grid rowconfigure $w 0 -weight 1 | |
d4e890e5 SP |
39 | |
40 | wm protocol $w WM_DELETE_WINDOW update | |
ea888f84 | 41 | bind $w.continue <Visibility> " |
d4e890e5 | 42 | grab $w |
ea888f84 | 43 | focus %W |
d4e890e5 | 44 | " |
c80d7be5 | 45 | wm deiconify $w |
d4e890e5 SP |
46 | tkwait window $w |
47 | ||
48 | $::main_status stop | |
49 | unlock_index | |
50 | rescan $after 0 | |
51 | return | |
52 | } | |
53 | ||
f4e9996b | 54 | $::main_status stop |
d4e890e5 SP |
55 | unlock_index |
56 | uplevel #0 $after | |
57 | } | |
58 | ||
f522c9b5 | 59 | proc update_indexinfo {msg pathList after} { |
699d5601 | 60 | global update_index_cp |
f522c9b5 SP |
61 | |
62 | if {![lock_index update]} return | |
63 | ||
64 | set update_index_cp 0 | |
65 | set pathList [lsort $pathList] | |
66 | set totalCnt [llength $pathList] | |
67 | set batch [expr {int($totalCnt * .01) + 1}] | |
68 | if {$batch > 25} {set batch 25} | |
69 | ||
1cad232f | 70 | $::main_status start $msg [mc "files"] |
0b812616 | 71 | set fd [git_write update-index -z --index-info] |
f522c9b5 SP |
72 | fconfigure $fd \ |
73 | -blocking 0 \ | |
74 | -buffering full \ | |
75 | -buffersize 512 \ | |
76 | -encoding binary \ | |
77 | -translation binary | |
78 | fileevent $fd writable [list \ | |
79 | write_update_indexinfo \ | |
80 | $fd \ | |
81 | $pathList \ | |
82 | $totalCnt \ | |
83 | $batch \ | |
f522c9b5 SP |
84 | $after \ |
85 | ] | |
86 | } | |
87 | ||
1cad232f | 88 | proc write_update_indexinfo {fd pathList totalCnt batch after} { |
699d5601 | 89 | global update_index_cp |
f522c9b5 SP |
90 | global file_states current_diff_path |
91 | ||
92 | if {$update_index_cp >= $totalCnt} { | |
d4e890e5 | 93 | _close_updateindex $fd $after |
f522c9b5 SP |
94 | return |
95 | } | |
96 | ||
97 | for {set i $batch} \ | |
98 | {$update_index_cp < $totalCnt && $i > 0} \ | |
99 | {incr i -1} { | |
100 | set path [lindex $pathList $update_index_cp] | |
101 | incr update_index_cp | |
102 | ||
103 | set s $file_states($path) | |
104 | switch -glob -- [lindex $s 0] { | |
105 | A? {set new _O} | |
7587f4d3 BW |
106 | MT - |
107 | TM - | |
e681cb7d | 108 | T_ {set new _T} |
7587f4d3 BW |
109 | M? {set new _M} |
110 | TD - | |
f522c9b5 SP |
111 | D_ {set new _D} |
112 | D? {set new _?} | |
113 | ?? {continue} | |
114 | } | |
115 | set info [lindex $s 2] | |
116 | if {$info eq {}} continue | |
117 | ||
e2039e94 | 118 | puts -nonewline $fd "$info\t[encoding convertto utf-8 $path]\0" |
f522c9b5 SP |
119 | display_file $path $new |
120 | } | |
121 | ||
1cad232f | 122 | $::main_status update $update_index_cp $totalCnt |
f522c9b5 SP |
123 | } |
124 | ||
125 | proc update_index {msg pathList after} { | |
699d5601 | 126 | global update_index_cp |
f522c9b5 SP |
127 | |
128 | if {![lock_index update]} return | |
129 | ||
130 | set update_index_cp 0 | |
131 | set pathList [lsort $pathList] | |
132 | set totalCnt [llength $pathList] | |
133 | set batch [expr {int($totalCnt * .01) + 1}] | |
134 | if {$batch > 25} {set batch 25} | |
135 | ||
1cad232f | 136 | $::main_status start $msg [mc "files"] |
0b812616 | 137 | set fd [git_write update-index --add --remove -z --stdin] |
f522c9b5 SP |
138 | fconfigure $fd \ |
139 | -blocking 0 \ | |
140 | -buffering full \ | |
141 | -buffersize 512 \ | |
142 | -encoding binary \ | |
143 | -translation binary | |
144 | fileevent $fd writable [list \ | |
145 | write_update_index \ | |
146 | $fd \ | |
147 | $pathList \ | |
148 | $totalCnt \ | |
149 | $batch \ | |
f522c9b5 SP |
150 | $after \ |
151 | ] | |
152 | } | |
153 | ||
1cad232f | 154 | proc write_update_index {fd pathList totalCnt batch after} { |
699d5601 | 155 | global update_index_cp |
f522c9b5 SP |
156 | global file_states current_diff_path |
157 | ||
158 | if {$update_index_cp >= $totalCnt} { | |
d4e890e5 | 159 | _close_updateindex $fd $after |
f522c9b5 SP |
160 | return |
161 | } | |
162 | ||
163 | for {set i $batch} \ | |
164 | {$update_index_cp < $totalCnt && $i > 0} \ | |
165 | {incr i -1} { | |
166 | set path [lindex $pathList $update_index_cp] | |
167 | incr update_index_cp | |
168 | ||
169 | switch -glob -- [lindex $file_states($path) 0] { | |
170 | AD {set new __} | |
171 | ?D {set new D_} | |
172 | _O - | |
7587f4d3 | 173 | AT - |
f522c9b5 | 174 | AM {set new A_} |
7587f4d3 BW |
175 | TM - |
176 | MT - | |
e681cb7d | 177 | _T {set new T_} |
ff515d81 | 178 | _U - |
f522c9b5 SP |
179 | U? { |
180 | if {[file exists $path]} { | |
181 | set new M_ | |
182 | } else { | |
183 | set new D_ | |
184 | } | |
185 | } | |
186 | ?M {set new M_} | |
187 | ?? {continue} | |
188 | } | |
e2039e94 | 189 | puts -nonewline $fd "[encoding convertto utf-8 $path]\0" |
f522c9b5 SP |
190 | display_file $path $new |
191 | } | |
192 | ||
1cad232f | 193 | $::main_status update $update_index_cp $totalCnt |
f522c9b5 SP |
194 | } |
195 | ||
196 | proc checkout_index {msg pathList after} { | |
699d5601 | 197 | global update_index_cp |
f522c9b5 SP |
198 | |
199 | if {![lock_index update]} return | |
200 | ||
201 | set update_index_cp 0 | |
202 | set pathList [lsort $pathList] | |
203 | set totalCnt [llength $pathList] | |
204 | set batch [expr {int($totalCnt * .01) + 1}] | |
205 | if {$batch > 25} {set batch 25} | |
206 | ||
1cad232f | 207 | $::main_status start $msg [mc "files"] |
0b812616 SP |
208 | set fd [git_write checkout-index \ |
209 | --index \ | |
210 | --quiet \ | |
211 | --force \ | |
212 | -z \ | |
213 | --stdin \ | |
214 | ] | |
f522c9b5 SP |
215 | fconfigure $fd \ |
216 | -blocking 0 \ | |
217 | -buffering full \ | |
218 | -buffersize 512 \ | |
219 | -encoding binary \ | |
220 | -translation binary | |
221 | fileevent $fd writable [list \ | |
222 | write_checkout_index \ | |
223 | $fd \ | |
224 | $pathList \ | |
225 | $totalCnt \ | |
226 | $batch \ | |
f522c9b5 SP |
227 | $after \ |
228 | ] | |
229 | } | |
230 | ||
1cad232f | 231 | proc write_checkout_index {fd pathList totalCnt batch after} { |
699d5601 | 232 | global update_index_cp |
f522c9b5 SP |
233 | global file_states current_diff_path |
234 | ||
235 | if {$update_index_cp >= $totalCnt} { | |
d4e890e5 | 236 | _close_updateindex $fd $after |
f522c9b5 SP |
237 | return |
238 | } | |
239 | ||
240 | for {set i $batch} \ | |
241 | {$update_index_cp < $totalCnt && $i > 0} \ | |
242 | {incr i -1} { | |
243 | set path [lindex $pathList $update_index_cp] | |
244 | incr update_index_cp | |
245 | switch -glob -- [lindex $file_states($path) 0] { | |
246 | U? {continue} | |
247 | ?M - | |
e681cb7d | 248 | ?T - |
f522c9b5 | 249 | ?D { |
e2039e94 | 250 | puts -nonewline $fd "[encoding convertto utf-8 $path]\0" |
f522c9b5 SP |
251 | display_file $path ?_ |
252 | } | |
253 | } | |
254 | } | |
255 | ||
1cad232f | 256 | $::main_status update $update_index_cp $totalCnt |
f522c9b5 SP |
257 | } |
258 | ||
259 | proc unstage_helper {txt paths} { | |
260 | global file_states current_diff_path | |
261 | ||
262 | if {![lock_index begin-update]} return | |
263 | ||
264 | set pathList [list] | |
265 | set after {} | |
266 | foreach path $paths { | |
267 | switch -glob -- [lindex $file_states($path) 0] { | |
268 | A? - | |
269 | M? - | |
7587f4d3 | 270 | T? - |
f522c9b5 SP |
271 | D? { |
272 | lappend pathList $path | |
273 | if {$path eq $current_diff_path} { | |
274 | set after {reshow_diff;} | |
275 | } | |
276 | } | |
277 | } | |
278 | } | |
279 | if {$pathList eq {}} { | |
280 | unlock_index | |
281 | } else { | |
282 | update_indexinfo \ | |
283 | $txt \ | |
284 | $pathList \ | |
699d5601 | 285 | [concat $after [list ui_ready]] |
f522c9b5 SP |
286 | } |
287 | } | |
288 | ||
289 | proc do_unstage_selection {} { | |
290 | global current_diff_path selected_paths | |
291 | ||
292 | if {[array size selected_paths] > 0} { | |
293 | unstage_helper \ | |
124356b6 | 294 | [mc "Unstaging selected files from commit"] \ |
f522c9b5 SP |
295 | [array names selected_paths] |
296 | } elseif {$current_diff_path ne {}} { | |
297 | unstage_helper \ | |
c8c4854b | 298 | [mc "Unstaging %s from commit" [short_path $current_diff_path]] \ |
f522c9b5 SP |
299 | [list $current_diff_path] |
300 | } | |
301 | } | |
302 | ||
303 | proc add_helper {txt paths} { | |
304 | global file_states current_diff_path | |
305 | ||
306 | if {![lock_index begin-update]} return | |
307 | ||
308 | set pathList [list] | |
309 | set after {} | |
310 | foreach path $paths { | |
311 | switch -glob -- [lindex $file_states($path) 0] { | |
0aea2842 AG |
312 | _U - |
313 | U? { | |
314 | if {$path eq $current_diff_path} { | |
315 | unlock_index | |
316 | merge_stage_workdir $path | |
317 | return | |
318 | } | |
319 | } | |
f522c9b5 SP |
320 | _O - |
321 | ?M - | |
322 | ?D - | |
0aea2842 | 323 | ?T { |
f522c9b5 SP |
324 | lappend pathList $path |
325 | if {$path eq $current_diff_path} { | |
326 | set after {reshow_diff;} | |
327 | } | |
328 | } | |
329 | } | |
330 | } | |
331 | if {$pathList eq {}} { | |
332 | unlock_index | |
333 | } else { | |
334 | update_index \ | |
335 | $txt \ | |
336 | $pathList \ | |
5e6d7768 | 337 | [concat $after {ui_status [mc "Ready to commit."]}] |
f522c9b5 SP |
338 | } |
339 | } | |
340 | ||
341 | proc do_add_selection {} { | |
342 | global current_diff_path selected_paths | |
343 | ||
344 | if {[array size selected_paths] > 0} { | |
345 | add_helper \ | |
124356b6 | 346 | [mc "Adding selected files"] \ |
f522c9b5 SP |
347 | [array names selected_paths] |
348 | } elseif {$current_diff_path ne {}} { | |
349 | add_helper \ | |
c8c4854b | 350 | [mc "Adding %s" [short_path $current_diff_path]] \ |
f522c9b5 SP |
351 | [list $current_diff_path] |
352 | } | |
353 | } | |
354 | ||
355 | proc do_add_all {} { | |
356 | global file_states | |
357 | ||
358 | set paths [list] | |
526aa2b2 | 359 | set untracked_paths [list] |
f522c9b5 SP |
360 | foreach path [array names file_states] { |
361 | switch -glob -- [lindex $file_states($path) 0] { | |
362 | U? {continue} | |
363 | ?M - | |
e681cb7d | 364 | ?T - |
f522c9b5 | 365 | ?D {lappend paths $path} |
526aa2b2 | 366 | ?O {lappend untracked_paths $path} |
856c2d75 HV |
367 | } |
368 | } | |
526aa2b2 | 369 | if {[llength $untracked_paths]} { |
bb196e26 BW |
370 | set reply 0 |
371 | switch -- [get_config gui.stageuntracked] { | |
372 | no { | |
373 | set reply 0 | |
374 | } | |
375 | yes { | |
376 | set reply 1 | |
377 | } | |
378 | ask - | |
379 | default { | |
99665fc5 PT |
380 | set reply [ask_popup [mc "Stage %d untracked files?" \ |
381 | [llength $untracked_paths]]] | |
bb196e26 BW |
382 | } |
383 | } | |
856c2d75 | 384 | if {$reply} { |
526aa2b2 | 385 | set paths [concat $paths $untracked_paths] |
f522c9b5 SP |
386 | } |
387 | } | |
124356b6 | 388 | add_helper [mc "Adding all changed files"] $paths |
f522c9b5 SP |
389 | } |
390 | ||
391 | proc revert_helper {txt paths} { | |
392 | global file_states current_diff_path | |
393 | ||
394 | if {![lock_index begin-update]} return | |
395 | ||
396 | set pathList [list] | |
397 | set after {} | |
398 | foreach path $paths { | |
399 | switch -glob -- [lindex $file_states($path) 0] { | |
400 | U? {continue} | |
401 | ?M - | |
e681cb7d | 402 | ?T - |
f522c9b5 SP |
403 | ?D { |
404 | lappend pathList $path | |
405 | if {$path eq $current_diff_path} { | |
406 | set after {reshow_diff;} | |
407 | } | |
408 | } | |
409 | } | |
410 | } | |
411 | ||
1ac17950 CS |
412 | |
413 | # Split question between singular and plural cases, because | |
414 | # such distinction is needed in some languages. Previously, the | |
415 | # code used "Revert changes in" for both, but that can't work | |
416 | # in languages where 'in' must be combined with word from | |
73fd416b | 417 | # rest of string (in different way for both cases of course). |
1ac17950 CS |
418 | # |
419 | # FIXME: Unfortunately, even that isn't enough in some languages | |
420 | # as they have quite complex plural-form rules. Unfortunately, | |
421 | # msgcat doesn't seem to support that kind of string translation. | |
422 | # | |
f522c9b5 SP |
423 | set n [llength $pathList] |
424 | if {$n == 0} { | |
425 | unlock_index | |
426 | return | |
427 | } elseif {$n == 1} { | |
1ac17950 | 428 | set query [mc "Revert changes in file %s?" [short_path [lindex $pathList]]] |
f522c9b5 | 429 | } else { |
1ac17950 | 430 | set query [mc "Revert changes in these %i files?" $n] |
f522c9b5 SP |
431 | } |
432 | ||
433 | set reply [tk_dialog \ | |
434 | .confirm_revert \ | |
435 | "[appname] ([reponame])" \ | |
d4544601 CS |
436 | "$query |
437 | ||
438 | [mc "Any unstaged changes will be permanently lost by the revert."]" \ | |
f522c9b5 SP |
439 | question \ |
440 | 1 \ | |
1ac17950 CS |
441 | [mc "Do Nothing"] \ |
442 | [mc "Revert Changes"] \ | |
f522c9b5 SP |
443 | ] |
444 | if {$reply == 1} { | |
445 | checkout_index \ | |
446 | $txt \ | |
447 | $pathList \ | |
699d5601 | 448 | [concat $after [list ui_ready]] |
f522c9b5 SP |
449 | } else { |
450 | unlock_index | |
451 | } | |
452 | } | |
453 | ||
454 | proc do_revert_selection {} { | |
455 | global current_diff_path selected_paths | |
456 | ||
457 | if {[array size selected_paths] > 0} { | |
458 | revert_helper \ | |
700e5603 | 459 | [mc "Reverting selected files"] \ |
f522c9b5 SP |
460 | [array names selected_paths] |
461 | } elseif {$current_diff_path ne {}} { | |
462 | revert_helper \ | |
700e5603 | 463 | [mc "Reverting %s" [short_path $current_diff_path]] \ |
f522c9b5 SP |
464 | [list $current_diff_path] |
465 | } | |
466 | } | |
467 | ||
468 | proc do_select_commit_type {} { | |
ba41b5b3 | 469 | global commit_type commit_type_is_amend |
f522c9b5 | 470 | |
ba41b5b3 | 471 | if {$commit_type_is_amend == 0 |
f522c9b5 SP |
472 | && [string match amend* $commit_type]} { |
473 | create_new_commit | |
ba41b5b3 | 474 | } elseif {$commit_type_is_amend == 1 |
f522c9b5 SP |
475 | && ![string match amend* $commit_type]} { |
476 | load_last_commit | |
477 | ||
478 | # The amend request was rejected... | |
479 | # | |
480 | if {![string match amend* $commit_type]} { | |
ba41b5b3 | 481 | set commit_type_is_amend 0 |
f522c9b5 SP |
482 | } |
483 | } | |
484 | } |