1 # git-gui index (add/remove) support
2 # Copyright (C) 2006, 2007 Shawn Pearce
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"]
10 proc _close_updateindex
{fd
after} {
11 fconfigure $fd -blocking 1
12 if {[catch {close $fd} err
]} {
15 wm title
$w [strcat
"[appname] ([reponame]): " [mc
"Index Error"]]
16 wm geometry
$w "+[winfo rootx .]+[winfo rooty .]"
21 [mc
"Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] \
26 button $w.buttons.
continue \
27 -text [mc
"Continue"] \
28 -command [list destroy $w]
29 pack $w.buttons.
continue -side right
-padx 5
30 button $w.buttons.unlock
\
31 -text [mc
"Unlock Index"] \
32 -command "destroy $w; _delete_indexlock"
33 pack $w.buttons.unlock
-side right
34 pack $w.buttons
-side bottom
-fill x
-pady 10 -padx 10
36 wm protocol
$w WM_DELETE_WINDOW
update
37 bind $w.buttons.
continue <Visibility
> "
39 focus $w.buttons.continue
54 proc update_indexinfo
{msg pathList
after} {
55 global update_index_cp
57 if {![lock_index
update]} return
60 set pathList
[lsort $pathList]
61 set totalCnt
[llength $pathList]
62 set batch
[expr {int
($totalCnt * .01) + 1}]
63 if {$batch > 25} {set batch
25}
65 $::main_status start
$msg [mc
"files"]
66 set fd
[git_write update-index
-z --index-info
]
73 fileevent $fd writable
[list \
74 write_update_indexinfo
\
83 proc write_update_indexinfo
{fd pathList totalCnt batch
after} {
84 global update_index_cp
85 global file_states current_diff_path
87 if {$update_index_cp >= $totalCnt} {
88 _close_updateindex
$fd $after
93 {$update_index_cp < $totalCnt && $i > 0} \
95 set path
[lindex $pathList $update_index_cp]
98 set s
$file_states($path)
99 switch -glob -- [lindex $s 0] {
107 set info [lindex $s 2]
108 if {$info eq
{}} continue
110 puts -nonewline $fd "$info\t[encoding convertto $path]\0"
111 display_file
$path $new
114 $::main_status update $update_index_cp $totalCnt
117 proc update_index
{msg pathList
after} {
118 global update_index_cp
120 if {![lock_index
update]} return
122 set update_index_cp
0
123 set pathList
[lsort $pathList]
124 set totalCnt
[llength $pathList]
125 set batch
[expr {int
($totalCnt * .01) + 1}]
126 if {$batch > 25} {set batch
25}
128 $::main_status start
$msg [mc
"files"]
129 set fd
[git_write update-index
--add --remove -z --stdin]
136 fileevent $fd writable
[list \
146 proc write_update_index
{fd pathList totalCnt batch
after} {
147 global update_index_cp
148 global file_states current_diff_path
150 if {$update_index_cp >= $totalCnt} {
151 _close_updateindex
$fd $after
156 {$update_index_cp < $totalCnt && $i > 0} \
158 set path
[lindex $pathList $update_index_cp]
161 switch -glob -- [lindex $file_states($path) 0] {
169 if {[file exists
$path]} {
178 puts -nonewline $fd "[encoding convertto $path]\0"
179 display_file
$path $new
182 $::main_status update $update_index_cp $totalCnt
185 proc checkout_index
{msg pathList
after} {
186 global update_index_cp
188 if {![lock_index
update]} return
190 set update_index_cp
0
191 set pathList
[lsort $pathList]
192 set totalCnt
[llength $pathList]
193 set batch
[expr {int
($totalCnt * .01) + 1}]
194 if {$batch > 25} {set batch
25}
196 $::main_status start
$msg [mc
"files"]
197 set fd
[git_write checkout-index
\
210 fileevent $fd writable
[list \
211 write_checkout_index
\
220 proc write_checkout_index
{fd pathList totalCnt batch
after} {
221 global update_index_cp
222 global file_states current_diff_path
224 if {$update_index_cp >= $totalCnt} {
225 _close_updateindex
$fd $after
230 {$update_index_cp < $totalCnt && $i > 0} \
232 set path
[lindex $pathList $update_index_cp]
234 switch -glob -- [lindex $file_states($path) 0] {
239 puts -nonewline $fd "[encoding convertto $path]\0"
240 display_file
$path ?_
245 $::main_status update $update_index_cp $totalCnt
248 proc unstage_helper
{txt paths
} {
249 global file_states current_diff_path
251 if {![lock_index begin-update
]} return
255 foreach path
$paths {
256 switch -glob -- [lindex $file_states($path) 0] {
261 lappend pathList
$path
262 if {$path eq
$current_diff_path} {
263 set after {reshow_diff
;}
268 if {$pathList eq
{}} {
274 [concat $after [list ui_ready
]]
278 proc do_unstage_selection
{} {
279 global current_diff_path selected_paths
281 if {[array size selected_paths
] > 0} {
283 {Unstaging selected files from commit
} \
284 [array names selected_paths
]
285 } elseif
{$current_diff_path ne
{}} {
287 [mc
"Unstaging %s from commit" [short_path
$current_diff_path]] \
288 [list $current_diff_path]
292 proc add_helper
{txt paths
} {
293 global file_states current_diff_path
295 if {![lock_index begin-update
]} return
299 foreach path
$paths {
300 switch -glob -- [lindex $file_states($path) 0] {
303 if {$path eq
$current_diff_path} {
305 merge_stage_workdir
$path
313 lappend pathList
$path
314 if {$path eq
$current_diff_path} {
315 set after {reshow_diff
;}
320 if {$pathList eq
{}} {
326 [concat $after {ui_status
[mc
"Ready to commit."]}]
330 proc do_add_selection
{} {
331 global current_diff_path selected_paths
333 if {[array size selected_paths
] > 0} {
335 {Adding selected files
} \
336 [array names selected_paths
]
337 } elseif
{$current_diff_path ne
{}} {
339 [mc
"Adding %s" [short_path
$current_diff_path]] \
340 [list $current_diff_path]
348 foreach path
[array names file_states
] {
349 switch -glob -- [lindex $file_states($path) 0] {
353 ?D
{lappend paths
$path}
356 add_helper
{Adding all changed files
} $paths
359 proc revert_helper
{txt paths
} {
360 global file_states current_diff_path
362 if {![lock_index begin-update
]} return
366 foreach path
$paths {
367 switch -glob -- [lindex $file_states($path) 0] {
372 lappend pathList
$path
373 if {$path eq
$current_diff_path} {
374 set after {reshow_diff
;}
381 # Split question between singular and plural cases, because
382 # such distinction is needed in some languages. Previously, the
383 # code used "Revert changes in" for both, but that can't work
384 # in languages where 'in' must be combined with word from
385 # rest of string (in diffrent way for both cases of course).
387 # FIXME: Unfortunately, even that isn't enough in some languages
388 # as they have quite complex plural-form rules. Unfortunately,
389 # msgcat doesn't seem to support that kind of string translation.
391 set n
[llength $pathList]
396 set query
[mc
"Revert changes in file %s?" [short_path
[lindex $pathList]]]
398 set query
[mc
"Revert changes in these %i files?" $n]
401 set reply
[tk_dialog \
403 "[appname] ([reponame])" \
406 [mc "Any unstaged changes will be permanently lost by the revert.
"]" \
410 [mc
"Revert Changes"] \
416 [concat $after [list ui_ready
]]
422 proc do_revert_selection
{} {
423 global current_diff_path selected_paths
425 if {[array size selected_paths
] > 0} {
427 [mc
"Reverting selected files"] \
428 [array names selected_paths
]
429 } elseif
{$current_diff_path ne
{}} {
431 [mc
"Reverting %s" [short_path
$current_diff_path]] \
432 [list $current_diff_path]
436 proc do_select_commit_type
{} {
437 global commit_type selected_commit_type
439 if {$selected_commit_type eq
{new
}
440 && [string match amend
* $commit_type]} {
442 } elseif
{$selected_commit_type eq
{amend
}
443 && ![string match amend
* $commit_type]} {
446 # The amend request was rejected...
448 if {![string match amend
* $commit_type]} {
449 set selected_commit_type new