]>
Commit | Line | Data |
---|---|---|
f522c9b5 SP |
1 | # git-gui index (add/remove) support |
2 | # Copyright (C) 2006, 2007 Shawn Pearce | |
3 | ||
4 | proc update_indexinfo {msg pathList after} { | |
5 | global update_index_cp ui_status_value | |
6 | ||
7 | if {![lock_index update]} return | |
8 | ||
9 | set update_index_cp 0 | |
10 | set pathList [lsort $pathList] | |
11 | set totalCnt [llength $pathList] | |
12 | set batch [expr {int($totalCnt * .01) + 1}] | |
13 | if {$batch > 25} {set batch 25} | |
14 | ||
15 | set ui_status_value [format \ | |
16 | "$msg... %i/%i files (%.2f%%)" \ | |
17 | $update_index_cp \ | |
18 | $totalCnt \ | |
19 | 0.0] | |
20 | set fd [open "| git update-index -z --index-info" w] | |
21 | fconfigure $fd \ | |
22 | -blocking 0 \ | |
23 | -buffering full \ | |
24 | -buffersize 512 \ | |
25 | -encoding binary \ | |
26 | -translation binary | |
27 | fileevent $fd writable [list \ | |
28 | write_update_indexinfo \ | |
29 | $fd \ | |
30 | $pathList \ | |
31 | $totalCnt \ | |
32 | $batch \ | |
33 | $msg \ | |
34 | $after \ | |
35 | ] | |
36 | } | |
37 | ||
38 | proc write_update_indexinfo {fd pathList totalCnt batch msg after} { | |
39 | global update_index_cp ui_status_value | |
40 | global file_states current_diff_path | |
41 | ||
42 | if {$update_index_cp >= $totalCnt} { | |
43 | close $fd | |
44 | unlock_index | |
45 | uplevel #0 $after | |
46 | return | |
47 | } | |
48 | ||
49 | for {set i $batch} \ | |
50 | {$update_index_cp < $totalCnt && $i > 0} \ | |
51 | {incr i -1} { | |
52 | set path [lindex $pathList $update_index_cp] | |
53 | incr update_index_cp | |
54 | ||
55 | set s $file_states($path) | |
56 | switch -glob -- [lindex $s 0] { | |
57 | A? {set new _O} | |
58 | M? {set new _M} | |
59 | D_ {set new _D} | |
60 | D? {set new _?} | |
61 | ?? {continue} | |
62 | } | |
63 | set info [lindex $s 2] | |
64 | if {$info eq {}} continue | |
65 | ||
66 | puts -nonewline $fd "$info\t[encoding convertto $path]\0" | |
67 | display_file $path $new | |
68 | } | |
69 | ||
70 | set ui_status_value [format \ | |
71 | "$msg... %i/%i files (%.2f%%)" \ | |
72 | $update_index_cp \ | |
73 | $totalCnt \ | |
74 | [expr {100.0 * $update_index_cp / $totalCnt}]] | |
75 | } | |
76 | ||
77 | proc update_index {msg pathList after} { | |
78 | global update_index_cp ui_status_value | |
79 | ||
80 | if {![lock_index update]} return | |
81 | ||
82 | set update_index_cp 0 | |
83 | set pathList [lsort $pathList] | |
84 | set totalCnt [llength $pathList] | |
85 | set batch [expr {int($totalCnt * .01) + 1}] | |
86 | if {$batch > 25} {set batch 25} | |
87 | ||
88 | set ui_status_value [format \ | |
89 | "$msg... %i/%i files (%.2f%%)" \ | |
90 | $update_index_cp \ | |
91 | $totalCnt \ | |
92 | 0.0] | |
93 | set fd [open "| git update-index --add --remove -z --stdin" w] | |
94 | fconfigure $fd \ | |
95 | -blocking 0 \ | |
96 | -buffering full \ | |
97 | -buffersize 512 \ | |
98 | -encoding binary \ | |
99 | -translation binary | |
100 | fileevent $fd writable [list \ | |
101 | write_update_index \ | |
102 | $fd \ | |
103 | $pathList \ | |
104 | $totalCnt \ | |
105 | $batch \ | |
106 | $msg \ | |
107 | $after \ | |
108 | ] | |
109 | } | |
110 | ||
111 | proc write_update_index {fd pathList totalCnt batch msg after} { | |
112 | global update_index_cp ui_status_value | |
113 | global file_states current_diff_path | |
114 | ||
115 | if {$update_index_cp >= $totalCnt} { | |
116 | close $fd | |
117 | unlock_index | |
118 | uplevel #0 $after | |
119 | return | |
120 | } | |
121 | ||
122 | for {set i $batch} \ | |
123 | {$update_index_cp < $totalCnt && $i > 0} \ | |
124 | {incr i -1} { | |
125 | set path [lindex $pathList $update_index_cp] | |
126 | incr update_index_cp | |
127 | ||
128 | switch -glob -- [lindex $file_states($path) 0] { | |
129 | AD {set new __} | |
130 | ?D {set new D_} | |
131 | _O - | |
132 | AM {set new A_} | |
133 | U? { | |
134 | if {[file exists $path]} { | |
135 | set new M_ | |
136 | } else { | |
137 | set new D_ | |
138 | } | |
139 | } | |
140 | ?M {set new M_} | |
141 | ?? {continue} | |
142 | } | |
143 | puts -nonewline $fd "[encoding convertto $path]\0" | |
144 | display_file $path $new | |
145 | } | |
146 | ||
147 | set ui_status_value [format \ | |
148 | "$msg... %i/%i files (%.2f%%)" \ | |
149 | $update_index_cp \ | |
150 | $totalCnt \ | |
151 | [expr {100.0 * $update_index_cp / $totalCnt}]] | |
152 | } | |
153 | ||
154 | proc checkout_index {msg pathList after} { | |
155 | global update_index_cp ui_status_value | |
156 | ||
157 | if {![lock_index update]} return | |
158 | ||
159 | set update_index_cp 0 | |
160 | set pathList [lsort $pathList] | |
161 | set totalCnt [llength $pathList] | |
162 | set batch [expr {int($totalCnt * .01) + 1}] | |
163 | if {$batch > 25} {set batch 25} | |
164 | ||
165 | set ui_status_value [format \ | |
166 | "$msg... %i/%i files (%.2f%%)" \ | |
167 | $update_index_cp \ | |
168 | $totalCnt \ | |
169 | 0.0] | |
170 | set cmd [list git checkout-index] | |
171 | lappend cmd --index | |
172 | lappend cmd --quiet | |
173 | lappend cmd --force | |
174 | lappend cmd -z | |
175 | lappend cmd --stdin | |
176 | set fd [open "| $cmd " w] | |
177 | fconfigure $fd \ | |
178 | -blocking 0 \ | |
179 | -buffering full \ | |
180 | -buffersize 512 \ | |
181 | -encoding binary \ | |
182 | -translation binary | |
183 | fileevent $fd writable [list \ | |
184 | write_checkout_index \ | |
185 | $fd \ | |
186 | $pathList \ | |
187 | $totalCnt \ | |
188 | $batch \ | |
189 | $msg \ | |
190 | $after \ | |
191 | ] | |
192 | } | |
193 | ||
194 | proc write_checkout_index {fd pathList totalCnt batch msg after} { | |
195 | global update_index_cp ui_status_value | |
196 | global file_states current_diff_path | |
197 | ||
198 | if {$update_index_cp >= $totalCnt} { | |
199 | close $fd | |
200 | unlock_index | |
201 | uplevel #0 $after | |
202 | return | |
203 | } | |
204 | ||
205 | for {set i $batch} \ | |
206 | {$update_index_cp < $totalCnt && $i > 0} \ | |
207 | {incr i -1} { | |
208 | set path [lindex $pathList $update_index_cp] | |
209 | incr update_index_cp | |
210 | switch -glob -- [lindex $file_states($path) 0] { | |
211 | U? {continue} | |
212 | ?M - | |
213 | ?D { | |
214 | puts -nonewline $fd "[encoding convertto $path]\0" | |
215 | display_file $path ?_ | |
216 | } | |
217 | } | |
218 | } | |
219 | ||
220 | set ui_status_value [format \ | |
221 | "$msg... %i/%i files (%.2f%%)" \ | |
222 | $update_index_cp \ | |
223 | $totalCnt \ | |
224 | [expr {100.0 * $update_index_cp / $totalCnt}]] | |
225 | } | |
226 | ||
227 | proc unstage_helper {txt paths} { | |
228 | global file_states current_diff_path | |
229 | ||
230 | if {![lock_index begin-update]} return | |
231 | ||
232 | set pathList [list] | |
233 | set after {} | |
234 | foreach path $paths { | |
235 | switch -glob -- [lindex $file_states($path) 0] { | |
236 | A? - | |
237 | M? - | |
238 | D? { | |
239 | lappend pathList $path | |
240 | if {$path eq $current_diff_path} { | |
241 | set after {reshow_diff;} | |
242 | } | |
243 | } | |
244 | } | |
245 | } | |
246 | if {$pathList eq {}} { | |
247 | unlock_index | |
248 | } else { | |
249 | update_indexinfo \ | |
250 | $txt \ | |
251 | $pathList \ | |
252 | [concat $after {set ui_status_value {Ready.}}] | |
253 | } | |
254 | } | |
255 | ||
256 | proc do_unstage_selection {} { | |
257 | global current_diff_path selected_paths | |
258 | ||
259 | if {[array size selected_paths] > 0} { | |
260 | unstage_helper \ | |
261 | {Unstaging selected files from commit} \ | |
262 | [array names selected_paths] | |
263 | } elseif {$current_diff_path ne {}} { | |
264 | unstage_helper \ | |
265 | "Unstaging [short_path $current_diff_path] from commit" \ | |
266 | [list $current_diff_path] | |
267 | } | |
268 | } | |
269 | ||
270 | proc add_helper {txt paths} { | |
271 | global file_states current_diff_path | |
272 | ||
273 | if {![lock_index begin-update]} return | |
274 | ||
275 | set pathList [list] | |
276 | set after {} | |
277 | foreach path $paths { | |
278 | switch -glob -- [lindex $file_states($path) 0] { | |
279 | _O - | |
280 | ?M - | |
281 | ?D - | |
282 | U? { | |
283 | lappend pathList $path | |
284 | if {$path eq $current_diff_path} { | |
285 | set after {reshow_diff;} | |
286 | } | |
287 | } | |
288 | } | |
289 | } | |
290 | if {$pathList eq {}} { | |
291 | unlock_index | |
292 | } else { | |
293 | update_index \ | |
294 | $txt \ | |
295 | $pathList \ | |
296 | [concat $after {set ui_status_value {Ready to commit.}}] | |
297 | } | |
298 | } | |
299 | ||
300 | proc do_add_selection {} { | |
301 | global current_diff_path selected_paths | |
302 | ||
303 | if {[array size selected_paths] > 0} { | |
304 | add_helper \ | |
305 | {Adding selected files} \ | |
306 | [array names selected_paths] | |
307 | } elseif {$current_diff_path ne {}} { | |
308 | add_helper \ | |
309 | "Adding [short_path $current_diff_path]" \ | |
310 | [list $current_diff_path] | |
311 | } | |
312 | } | |
313 | ||
314 | proc do_add_all {} { | |
315 | global file_states | |
316 | ||
317 | set paths [list] | |
318 | foreach path [array names file_states] { | |
319 | switch -glob -- [lindex $file_states($path) 0] { | |
320 | U? {continue} | |
321 | ?M - | |
322 | ?D {lappend paths $path} | |
323 | } | |
324 | } | |
325 | add_helper {Adding all changed files} $paths | |
326 | } | |
327 | ||
328 | proc revert_helper {txt paths} { | |
329 | global file_states current_diff_path | |
330 | ||
331 | if {![lock_index begin-update]} return | |
332 | ||
333 | set pathList [list] | |
334 | set after {} | |
335 | foreach path $paths { | |
336 | switch -glob -- [lindex $file_states($path) 0] { | |
337 | U? {continue} | |
338 | ?M - | |
339 | ?D { | |
340 | lappend pathList $path | |
341 | if {$path eq $current_diff_path} { | |
342 | set after {reshow_diff;} | |
343 | } | |
344 | } | |
345 | } | |
346 | } | |
347 | ||
348 | set n [llength $pathList] | |
349 | if {$n == 0} { | |
350 | unlock_index | |
351 | return | |
352 | } elseif {$n == 1} { | |
353 | set s "[short_path [lindex $pathList]]" | |
354 | } else { | |
355 | set s "these $n files" | |
356 | } | |
357 | ||
358 | set reply [tk_dialog \ | |
359 | .confirm_revert \ | |
360 | "[appname] ([reponame])" \ | |
361 | "Revert changes in $s? | |
362 | ||
363 | Any unadded changes will be permanently lost by the revert." \ | |
364 | question \ | |
365 | 1 \ | |
366 | {Do Nothing} \ | |
367 | {Revert Changes} \ | |
368 | ] | |
369 | if {$reply == 1} { | |
370 | checkout_index \ | |
371 | $txt \ | |
372 | $pathList \ | |
373 | [concat $after {set ui_status_value {Ready.}}] | |
374 | } else { | |
375 | unlock_index | |
376 | } | |
377 | } | |
378 | ||
379 | proc do_revert_selection {} { | |
380 | global current_diff_path selected_paths | |
381 | ||
382 | if {[array size selected_paths] > 0} { | |
383 | revert_helper \ | |
384 | {Reverting selected files} \ | |
385 | [array names selected_paths] | |
386 | } elseif {$current_diff_path ne {}} { | |
387 | revert_helper \ | |
388 | "Reverting [short_path $current_diff_path]" \ | |
389 | [list $current_diff_path] | |
390 | } | |
391 | } | |
392 | ||
393 | proc do_select_commit_type {} { | |
394 | global commit_type selected_commit_type | |
395 | ||
396 | if {$selected_commit_type eq {new} | |
397 | && [string match amend* $commit_type]} { | |
398 | create_new_commit | |
399 | } elseif {$selected_commit_type eq {amend} | |
400 | && ![string match amend* $commit_type]} { | |
401 | load_last_commit | |
402 | ||
403 | # The amend request was rejected... | |
404 | # | |
405 | if {![string match amend* $commit_type]} { | |
406 | set selected_commit_type new | |
407 | } | |
408 | } | |
409 | } |