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} {
12 fconfigure $fd -blocking 1
13 if {[catch {close $fd} err
]} {
17 wm title
$w [strcat
"[appname] ([reponame]): " [mc
"Index Error"]]
18 wm geometry
$w "+[winfo rootx .]+[winfo rooty .]"
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 \
23 -background [get_bg_color
$w]
24 $w.msg tag configure bold
-font font_uibold
-justify center
25 ${NS
}::scrollbar $w.vs
-command [list $w.msg yview
]
26 $w.msg insert end
$s bold
\n\n$err {}
27 $w.msg configure
-state disabled
29 ${NS
}::button $w.
continue \
30 -text [mc
"Continue"] \
31 -command [list destroy $w]
32 ${NS
}::button $w.unlock
\
33 -text [mc
"Unlock Index"] \
34 -command "destroy $w; _delete_indexlock"
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
40 wm protocol
$w WM_DELETE_WINDOW
update
41 bind $w.
continue <Visibility
> "
59 proc update_indexinfo
{msg pathList
after} {
60 global update_index_cp
62 if {![lock_index
update]} return
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}
70 $::main_status start
$msg [mc
"files"]
71 set fd
[git_write update-index
-z --index-info
]
78 fileevent $fd writable
[list \
79 write_update_indexinfo
\
88 proc write_update_indexinfo
{fd pathList totalCnt batch
after} {
89 global update_index_cp
90 global file_states current_diff_path
92 if {$update_index_cp >= $totalCnt} {
93 _close_updateindex
$fd $after
98 {$update_index_cp < $totalCnt && $i > 0} \
100 set path
[lindex $pathList $update_index_cp]
103 set s
$file_states($path)
104 switch -glob -- [lindex $s 0] {
115 set info [lindex $s 2]
116 if {$info eq
{}} continue
118 puts -nonewline $fd "$info\t[encoding convertto $path]\0"
119 display_file
$path $new
122 $::main_status update $update_index_cp $totalCnt
125 proc update_index
{msg pathList
after} {
126 global update_index_cp
128 if {![lock_index
update]} return
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}
136 $::main_status start
$msg [mc
"files"]
137 set fd
[git_write update-index
--add --remove -z --stdin]
144 fileevent $fd writable
[list \
154 proc write_update_index
{fd pathList totalCnt batch
after} {
155 global update_index_cp
156 global file_states current_diff_path
158 if {$update_index_cp >= $totalCnt} {
159 _close_updateindex
$fd $after
164 {$update_index_cp < $totalCnt && $i > 0} \
166 set path
[lindex $pathList $update_index_cp]
169 switch -glob -- [lindex $file_states($path) 0] {
180 if {[file exists
$path]} {
189 puts -nonewline $fd "[encoding convertto $path]\0"
190 display_file
$path $new
193 $::main_status update $update_index_cp $totalCnt
196 proc checkout_index
{msg pathList
after} {
197 global update_index_cp
199 if {![lock_index
update]} return
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}
207 $::main_status start
$msg [mc
"files"]
208 set fd
[git_write checkout-index
\
221 fileevent $fd writable
[list \
222 write_checkout_index
\
231 proc write_checkout_index
{fd pathList totalCnt batch
after} {
232 global update_index_cp
233 global file_states current_diff_path
235 if {$update_index_cp >= $totalCnt} {
236 _close_updateindex
$fd $after
241 {$update_index_cp < $totalCnt && $i > 0} \
243 set path
[lindex $pathList $update_index_cp]
245 switch -glob -- [lindex $file_states($path) 0] {
250 puts -nonewline $fd "[encoding convertto $path]\0"
251 display_file
$path ?_
256 $::main_status update $update_index_cp $totalCnt
259 proc unstage_helper
{txt paths
} {
260 global file_states current_diff_path
262 if {![lock_index begin-update
]} return
266 foreach path
$paths {
267 switch -glob -- [lindex $file_states($path) 0] {
272 lappend pathList
$path
273 if {$path eq
$current_diff_path} {
274 set after {reshow_diff
;}
279 if {$pathList eq
{}} {
285 [concat $after [list ui_ready
]]
289 proc do_unstage_selection
{} {
290 global current_diff_path selected_paths
292 if {[array size selected_paths
] > 0} {
294 {Unstaging selected files from commit
} \
295 [array names selected_paths
]
296 } elseif
{$current_diff_path ne
{}} {
298 [mc
"Unstaging %s from commit" [short_path
$current_diff_path]] \
299 [list $current_diff_path]
303 proc add_helper
{txt paths
} {
304 global file_states current_diff_path
306 if {![lock_index begin-update
]} return
310 foreach path
$paths {
311 switch -glob -- [lindex $file_states($path) 0] {
314 if {$path eq
$current_diff_path} {
316 merge_stage_workdir
$path
324 lappend pathList
$path
325 if {$path eq
$current_diff_path} {
326 set after {reshow_diff
;}
331 if {$pathList eq
{}} {
337 [concat $after {ui_status
[mc
"Ready to commit."]}]
341 proc do_add_selection
{} {
342 global current_diff_path selected_paths
344 if {[array size selected_paths
] > 0} {
346 {Adding selected files
} \
347 [array names selected_paths
]
348 } elseif
{$current_diff_path ne
{}} {
350 [mc
"Adding %s" [short_path
$current_diff_path]] \
351 [list $current_diff_path]
359 set untracked_paths
[list]
360 foreach path
[array names file_states
] {
361 switch -glob -- [lindex $file_states($path) 0] {
365 ?D
{lappend paths
$path}
366 ?O
{lappend untracked_paths
$path}
369 if {[llength $untracked_paths]} {
371 switch -- [get_config gui.stageuntracked
] {
380 set reply
[ask_popup
[mc
"Stage %d untracked files?" \
381 [llength $untracked_paths]]]
385 set paths
[concat $paths $untracked_paths]
388 add_helper
{Adding all changed files
} $paths
391 proc revert_helper
{txt paths
} {
392 global file_states current_diff_path
394 if {![lock_index begin-update
]} return
398 foreach path
$paths {
399 switch -glob -- [lindex $file_states($path) 0] {
404 lappend pathList
$path
405 if {$path eq
$current_diff_path} {
406 set after {reshow_diff
;}
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
417 # rest of string (in diffrent way for both cases of course).
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.
423 set n
[llength $pathList]
428 set query
[mc
"Revert changes in file %s?" [short_path
[lindex $pathList]]]
430 set query
[mc
"Revert changes in these %i files?" $n]
433 set reply
[tk_dialog \
435 "[appname] ([reponame])" \
438 [mc "Any unstaged changes will be permanently lost by the revert.
"]" \
442 [mc
"Revert Changes"] \
448 [concat $after [list ui_ready
]]
454 proc do_revert_selection
{} {
455 global current_diff_path selected_paths
457 if {[array size selected_paths
] > 0} {
459 [mc
"Reverting selected files"] \
460 [array names selected_paths
]
461 } elseif
{$current_diff_path ne
{}} {
463 [mc
"Reverting %s" [short_path
$current_diff_path]] \
464 [list $current_diff_path]
468 proc do_select_commit_type
{} {
469 global commit_type selected_commit_type
471 if {$selected_commit_type eq
{new
}
472 && [string match amend
* $commit_type]} {
474 } elseif
{$selected_commit_type eq
{amend
}
475 && ![string match amend
* $commit_type]} {
478 # The amend request was rejected...
480 if {![string match amend
* $commit_type]} {
481 set selected_commit_type new