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 .]"
17 set s
[mc
"Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."]
18 text $w.msg
-yscrollcommand [list $w.vs
set] \
19 -width [string length
$s] -relief flat
\
20 -borderwidth 0 -highlightthickness 0 \
21 -background [$w cget
-background]
22 $w.msg tag configure bold
-font font_uibold
-justify center
23 scrollbar $w.vs
-command [list $w.msg yview
]
24 $w.msg insert end
$s bold
\n\n$err {}
25 $w.msg configure
-state disabled
28 -text [mc
"Continue"] \
29 -command [list destroy $w]
31 -text [mc
"Unlock Index"] \
32 -command "destroy $w; _delete_indexlock"
33 grid $w.msg
- $w.vs
-sticky news
34 grid $w.unlock
$w.
continue - -sticky se
-padx 2 -pady 2
35 grid columnconfigure
$w 0 -weight 1
36 grid rowconfigure
$w 0 -weight 1
38 wm protocol
$w WM_DELETE_WINDOW
update
39 bind $w.
continue <Visibility
> "
56 proc update_indexinfo
{msg pathList
after} {
57 global update_index_cp
59 if {![lock_index
update]} return
62 set pathList
[lsort $pathList]
63 set totalCnt
[llength $pathList]
64 set batch
[expr {int
($totalCnt * .01) + 1}]
65 if {$batch > 25} {set batch
25}
67 $::main_status start
$msg [mc
"files"]
68 set fd
[git_write update-index
-z --index-info
]
75 fileevent $fd writable
[list \
76 write_update_indexinfo
\
85 proc write_update_indexinfo
{fd pathList totalCnt batch
after} {
86 global update_index_cp
87 global file_states current_diff_path
89 if {$update_index_cp >= $totalCnt} {
90 _close_updateindex
$fd $after
95 {$update_index_cp < $totalCnt && $i > 0} \
97 set path
[lindex $pathList $update_index_cp]
100 set s
$file_states($path)
101 switch -glob -- [lindex $s 0] {
109 set info [lindex $s 2]
110 if {$info eq
{}} continue
112 puts -nonewline $fd "$info\t[encoding convertto $path]\0"
113 display_file
$path $new
116 $::main_status update $update_index_cp $totalCnt
119 proc update_index
{msg pathList
after} {
120 global update_index_cp
122 if {![lock_index
update]} return
124 set update_index_cp
0
125 set pathList
[lsort $pathList]
126 set totalCnt
[llength $pathList]
127 set batch
[expr {int
($totalCnt * .01) + 1}]
128 if {$batch > 25} {set batch
25}
130 $::main_status start
$msg [mc
"files"]
131 set fd
[git_write update-index
--add --remove -z --stdin]
138 fileevent $fd writable
[list \
148 proc write_update_index
{fd pathList totalCnt batch
after} {
149 global update_index_cp
150 global file_states current_diff_path
152 if {$update_index_cp >= $totalCnt} {
153 _close_updateindex
$fd $after
158 {$update_index_cp < $totalCnt && $i > 0} \
160 set path
[lindex $pathList $update_index_cp]
163 switch -glob -- [lindex $file_states($path) 0] {
171 if {[file exists
$path]} {
180 puts -nonewline $fd "[encoding convertto $path]\0"
181 display_file
$path $new
184 $::main_status update $update_index_cp $totalCnt
187 proc checkout_index
{msg pathList
after} {
188 global update_index_cp
190 if {![lock_index
update]} return
192 set update_index_cp
0
193 set pathList
[lsort $pathList]
194 set totalCnt
[llength $pathList]
195 set batch
[expr {int
($totalCnt * .01) + 1}]
196 if {$batch > 25} {set batch
25}
198 $::main_status start
$msg [mc
"files"]
199 set fd
[git_write checkout-index
\
212 fileevent $fd writable
[list \
213 write_checkout_index
\
222 proc write_checkout_index
{fd pathList totalCnt batch
after} {
223 global update_index_cp
224 global file_states current_diff_path
226 if {$update_index_cp >= $totalCnt} {
227 _close_updateindex
$fd $after
232 {$update_index_cp < $totalCnt && $i > 0} \
234 set path
[lindex $pathList $update_index_cp]
236 switch -glob -- [lindex $file_states($path) 0] {
241 puts -nonewline $fd "[encoding convertto $path]\0"
242 display_file
$path ?_
247 $::main_status update $update_index_cp $totalCnt
250 proc unstage_helper
{txt paths
} {
251 global file_states current_diff_path
253 if {![lock_index begin-update
]} return
257 foreach path
$paths {
258 switch -glob -- [lindex $file_states($path) 0] {
263 lappend pathList
$path
264 if {$path eq
$current_diff_path} {
265 set after {reshow_diff
;}
270 if {$pathList eq
{}} {
276 [concat $after [list ui_ready
]]
280 proc do_unstage_selection
{} {
281 global current_diff_path selected_paths
283 if {[array size selected_paths
] > 0} {
285 {Unstaging selected files from commit
} \
286 [array names selected_paths
]
287 } elseif
{$current_diff_path ne
{}} {
289 [mc
"Unstaging %s from commit" [short_path
$current_diff_path]] \
290 [list $current_diff_path]
294 proc add_helper
{txt paths
} {
295 global file_states current_diff_path
297 if {![lock_index begin-update
]} return
301 foreach path
$paths {
302 switch -glob -- [lindex $file_states($path) 0] {
305 if {$path eq
$current_diff_path} {
307 merge_stage_workdir
$path
315 lappend pathList
$path
316 if {$path eq
$current_diff_path} {
317 set after {reshow_diff
;}
322 if {$pathList eq
{}} {
328 [concat $after {ui_status
[mc
"Ready to commit."]}]
332 proc do_add_selection
{} {
333 global current_diff_path selected_paths
335 if {[array size selected_paths
] > 0} {
337 {Adding selected files
} \
338 [array names selected_paths
]
339 } elseif
{$current_diff_path ne
{}} {
341 [mc
"Adding %s" [short_path
$current_diff_path]] \
342 [list $current_diff_path]
350 foreach path
[array names file_states
] {
351 switch -glob -- [lindex $file_states($path) 0] {
355 ?D
{lappend paths
$path}
358 add_helper
{Adding all changed files
} $paths
361 proc revert_helper
{txt paths
} {
362 global file_states current_diff_path
364 if {![lock_index begin-update
]} return
368 foreach path
$paths {
369 switch -glob -- [lindex $file_states($path) 0] {
374 lappend pathList
$path
375 if {$path eq
$current_diff_path} {
376 set after {reshow_diff
;}
383 # Split question between singular and plural cases, because
384 # such distinction is needed in some languages. Previously, the
385 # code used "Revert changes in" for both, but that can't work
386 # in languages where 'in' must be combined with word from
387 # rest of string (in diffrent way for both cases of course).
389 # FIXME: Unfortunately, even that isn't enough in some languages
390 # as they have quite complex plural-form rules. Unfortunately,
391 # msgcat doesn't seem to support that kind of string translation.
393 set n
[llength $pathList]
398 set query
[mc
"Revert changes in file %s?" [short_path
[lindex $pathList]]]
400 set query
[mc
"Revert changes in these %i files?" $n]
403 set reply
[tk_dialog \
405 "[appname] ([reponame])" \
408 [mc "Any unstaged changes will be permanently lost by the revert.
"]" \
412 [mc
"Revert Changes"] \
418 [concat $after [list ui_ready
]]
424 proc do_revert_selection
{} {
425 global current_diff_path selected_paths
427 if {[array size selected_paths
] > 0} {
429 [mc
"Reverting selected files"] \
430 [array names selected_paths
]
431 } elseif
{$current_diff_path ne
{}} {
433 [mc
"Reverting %s" [short_path
$current_diff_path]] \
434 [list $current_diff_path]
438 proc do_select_commit_type
{} {
439 global commit_type selected_commit_type
441 if {$selected_commit_type eq
{new
}
442 && [string match amend
* $commit_type]} {
444 } elseif
{$selected_commit_type eq
{amend
}
445 && ![string match amend
* $commit_type]} {
448 # The amend request was rejected...
450 if {![string match amend
* $commit_type]} {
451 set selected_commit_type new