You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
409 lines
8.1 KiB
409 lines
8.1 KiB
# git-gui index (add/remove) support |
|
# Copyright (C) 2006, 2007 Shawn Pearce |
|
|
|
proc update_indexinfo {msg pathList after} { |
|
global update_index_cp ui_status_value |
|
|
|
if {![lock_index update]} return |
|
|
|
set update_index_cp 0 |
|
set pathList [lsort $pathList] |
|
set totalCnt [llength $pathList] |
|
set batch [expr {int($totalCnt * .01) + 1}] |
|
if {$batch > 25} {set batch 25} |
|
|
|
set ui_status_value [format \ |
|
"$msg... %i/%i files (%.2f%%)" \ |
|
$update_index_cp \ |
|
$totalCnt \ |
|
0.0] |
|
set fd [open "| git update-index -z --index-info" w] |
|
fconfigure $fd \ |
|
-blocking 0 \ |
|
-buffering full \ |
|
-buffersize 512 \ |
|
-encoding binary \ |
|
-translation binary |
|
fileevent $fd writable [list \ |
|
write_update_indexinfo \ |
|
$fd \ |
|
$pathList \ |
|
$totalCnt \ |
|
$batch \ |
|
$msg \ |
|
$after \ |
|
] |
|
} |
|
|
|
proc write_update_indexinfo {fd pathList totalCnt batch msg after} { |
|
global update_index_cp ui_status_value |
|
global file_states current_diff_path |
|
|
|
if {$update_index_cp >= $totalCnt} { |
|
close $fd |
|
unlock_index |
|
uplevel #0 $after |
|
return |
|
} |
|
|
|
for {set i $batch} \ |
|
{$update_index_cp < $totalCnt && $i > 0} \ |
|
{incr i -1} { |
|
set path [lindex $pathList $update_index_cp] |
|
incr update_index_cp |
|
|
|
set s $file_states($path) |
|
switch -glob -- [lindex $s 0] { |
|
A? {set new _O} |
|
M? {set new _M} |
|
D_ {set new _D} |
|
D? {set new _?} |
|
?? {continue} |
|
} |
|
set info [lindex $s 2] |
|
if {$info eq {}} continue |
|
|
|
puts -nonewline $fd "$info\t[encoding convertto $path]\0" |
|
display_file $path $new |
|
} |
|
|
|
set ui_status_value [format \ |
|
"$msg... %i/%i files (%.2f%%)" \ |
|
$update_index_cp \ |
|
$totalCnt \ |
|
[expr {100.0 * $update_index_cp / $totalCnt}]] |
|
} |
|
|
|
proc update_index {msg pathList after} { |
|
global update_index_cp ui_status_value |
|
|
|
if {![lock_index update]} return |
|
|
|
set update_index_cp 0 |
|
set pathList [lsort $pathList] |
|
set totalCnt [llength $pathList] |
|
set batch [expr {int($totalCnt * .01) + 1}] |
|
if {$batch > 25} {set batch 25} |
|
|
|
set ui_status_value [format \ |
|
"$msg... %i/%i files (%.2f%%)" \ |
|
$update_index_cp \ |
|
$totalCnt \ |
|
0.0] |
|
set fd [open "| git update-index --add --remove -z --stdin" w] |
|
fconfigure $fd \ |
|
-blocking 0 \ |
|
-buffering full \ |
|
-buffersize 512 \ |
|
-encoding binary \ |
|
-translation binary |
|
fileevent $fd writable [list \ |
|
write_update_index \ |
|
$fd \ |
|
$pathList \ |
|
$totalCnt \ |
|
$batch \ |
|
$msg \ |
|
$after \ |
|
] |
|
} |
|
|
|
proc write_update_index {fd pathList totalCnt batch msg after} { |
|
global update_index_cp ui_status_value |
|
global file_states current_diff_path |
|
|
|
if {$update_index_cp >= $totalCnt} { |
|
close $fd |
|
unlock_index |
|
uplevel #0 $after |
|
return |
|
} |
|
|
|
for {set i $batch} \ |
|
{$update_index_cp < $totalCnt && $i > 0} \ |
|
{incr i -1} { |
|
set path [lindex $pathList $update_index_cp] |
|
incr update_index_cp |
|
|
|
switch -glob -- [lindex $file_states($path) 0] { |
|
AD {set new __} |
|
?D {set new D_} |
|
_O - |
|
AM {set new A_} |
|
U? { |
|
if {[file exists $path]} { |
|
set new M_ |
|
} else { |
|
set new D_ |
|
} |
|
} |
|
?M {set new M_} |
|
?? {continue} |
|
} |
|
puts -nonewline $fd "[encoding convertto $path]\0" |
|
display_file $path $new |
|
} |
|
|
|
set ui_status_value [format \ |
|
"$msg... %i/%i files (%.2f%%)" \ |
|
$update_index_cp \ |
|
$totalCnt \ |
|
[expr {100.0 * $update_index_cp / $totalCnt}]] |
|
} |
|
|
|
proc checkout_index {msg pathList after} { |
|
global update_index_cp ui_status_value |
|
|
|
if {![lock_index update]} return |
|
|
|
set update_index_cp 0 |
|
set pathList [lsort $pathList] |
|
set totalCnt [llength $pathList] |
|
set batch [expr {int($totalCnt * .01) + 1}] |
|
if {$batch > 25} {set batch 25} |
|
|
|
set ui_status_value [format \ |
|
"$msg... %i/%i files (%.2f%%)" \ |
|
$update_index_cp \ |
|
$totalCnt \ |
|
0.0] |
|
set cmd [list git checkout-index] |
|
lappend cmd --index |
|
lappend cmd --quiet |
|
lappend cmd --force |
|
lappend cmd -z |
|
lappend cmd --stdin |
|
set fd [open "| $cmd " w] |
|
fconfigure $fd \ |
|
-blocking 0 \ |
|
-buffering full \ |
|
-buffersize 512 \ |
|
-encoding binary \ |
|
-translation binary |
|
fileevent $fd writable [list \ |
|
write_checkout_index \ |
|
$fd \ |
|
$pathList \ |
|
$totalCnt \ |
|
$batch \ |
|
$msg \ |
|
$after \ |
|
] |
|
} |
|
|
|
proc write_checkout_index {fd pathList totalCnt batch msg after} { |
|
global update_index_cp ui_status_value |
|
global file_states current_diff_path |
|
|
|
if {$update_index_cp >= $totalCnt} { |
|
close $fd |
|
unlock_index |
|
uplevel #0 $after |
|
return |
|
} |
|
|
|
for {set i $batch} \ |
|
{$update_index_cp < $totalCnt && $i > 0} \ |
|
{incr i -1} { |
|
set path [lindex $pathList $update_index_cp] |
|
incr update_index_cp |
|
switch -glob -- [lindex $file_states($path) 0] { |
|
U? {continue} |
|
?M - |
|
?D { |
|
puts -nonewline $fd "[encoding convertto $path]\0" |
|
display_file $path ?_ |
|
} |
|
} |
|
} |
|
|
|
set ui_status_value [format \ |
|
"$msg... %i/%i files (%.2f%%)" \ |
|
$update_index_cp \ |
|
$totalCnt \ |
|
[expr {100.0 * $update_index_cp / $totalCnt}]] |
|
} |
|
|
|
proc unstage_helper {txt paths} { |
|
global file_states current_diff_path |
|
|
|
if {![lock_index begin-update]} return |
|
|
|
set pathList [list] |
|
set after {} |
|
foreach path $paths { |
|
switch -glob -- [lindex $file_states($path) 0] { |
|
A? - |
|
M? - |
|
D? { |
|
lappend pathList $path |
|
if {$path eq $current_diff_path} { |
|
set after {reshow_diff;} |
|
} |
|
} |
|
} |
|
} |
|
if {$pathList eq {}} { |
|
unlock_index |
|
} else { |
|
update_indexinfo \ |
|
$txt \ |
|
$pathList \ |
|
[concat $after {set ui_status_value {Ready.}}] |
|
} |
|
} |
|
|
|
proc do_unstage_selection {} { |
|
global current_diff_path selected_paths |
|
|
|
if {[array size selected_paths] > 0} { |
|
unstage_helper \ |
|
{Unstaging selected files from commit} \ |
|
[array names selected_paths] |
|
} elseif {$current_diff_path ne {}} { |
|
unstage_helper \ |
|
"Unstaging [short_path $current_diff_path] from commit" \ |
|
[list $current_diff_path] |
|
} |
|
} |
|
|
|
proc add_helper {txt paths} { |
|
global file_states current_diff_path |
|
|
|
if {![lock_index begin-update]} return |
|
|
|
set pathList [list] |
|
set after {} |
|
foreach path $paths { |
|
switch -glob -- [lindex $file_states($path) 0] { |
|
_O - |
|
?M - |
|
?D - |
|
U? { |
|
lappend pathList $path |
|
if {$path eq $current_diff_path} { |
|
set after {reshow_diff;} |
|
} |
|
} |
|
} |
|
} |
|
if {$pathList eq {}} { |
|
unlock_index |
|
} else { |
|
update_index \ |
|
$txt \ |
|
$pathList \ |
|
[concat $after {set ui_status_value {Ready to commit.}}] |
|
} |
|
} |
|
|
|
proc do_add_selection {} { |
|
global current_diff_path selected_paths |
|
|
|
if {[array size selected_paths] > 0} { |
|
add_helper \ |
|
{Adding selected files} \ |
|
[array names selected_paths] |
|
} elseif {$current_diff_path ne {}} { |
|
add_helper \ |
|
"Adding [short_path $current_diff_path]" \ |
|
[list $current_diff_path] |
|
} |
|
} |
|
|
|
proc do_add_all {} { |
|
global file_states |
|
|
|
set paths [list] |
|
foreach path [array names file_states] { |
|
switch -glob -- [lindex $file_states($path) 0] { |
|
U? {continue} |
|
?M - |
|
?D {lappend paths $path} |
|
} |
|
} |
|
add_helper {Adding all changed files} $paths |
|
} |
|
|
|
proc revert_helper {txt paths} { |
|
global file_states current_diff_path |
|
|
|
if {![lock_index begin-update]} return |
|
|
|
set pathList [list] |
|
set after {} |
|
foreach path $paths { |
|
switch -glob -- [lindex $file_states($path) 0] { |
|
U? {continue} |
|
?M - |
|
?D { |
|
lappend pathList $path |
|
if {$path eq $current_diff_path} { |
|
set after {reshow_diff;} |
|
} |
|
} |
|
} |
|
} |
|
|
|
set n [llength $pathList] |
|
if {$n == 0} { |
|
unlock_index |
|
return |
|
} elseif {$n == 1} { |
|
set s "[short_path [lindex $pathList]]" |
|
} else { |
|
set s "these $n files" |
|
} |
|
|
|
set reply [tk_dialog \ |
|
.confirm_revert \ |
|
"[appname] ([reponame])" \ |
|
"Revert changes in $s? |
|
|
|
Any unadded changes will be permanently lost by the revert." \ |
|
question \ |
|
1 \ |
|
{Do Nothing} \ |
|
{Revert Changes} \ |
|
] |
|
if {$reply == 1} { |
|
checkout_index \ |
|
$txt \ |
|
$pathList \ |
|
[concat $after {set ui_status_value {Ready.}}] |
|
} else { |
|
unlock_index |
|
} |
|
} |
|
|
|
proc do_revert_selection {} { |
|
global current_diff_path selected_paths |
|
|
|
if {[array size selected_paths] > 0} { |
|
revert_helper \ |
|
{Reverting selected files} \ |
|
[array names selected_paths] |
|
} elseif {$current_diff_path ne {}} { |
|
revert_helper \ |
|
"Reverting [short_path $current_diff_path]" \ |
|
[list $current_diff_path] |
|
} |
|
} |
|
|
|
proc do_select_commit_type {} { |
|
global commit_type selected_commit_type |
|
|
|
if {$selected_commit_type eq {new} |
|
&& [string match amend* $commit_type]} { |
|
create_new_commit |
|
} elseif {$selected_commit_type eq {amend} |
|
&& ![string match amend* $commit_type]} { |
|
load_last_commit |
|
|
|
# The amend request was rejected... |
|
# |
|
if {![string match amend* $commit_type]} { |
|
set selected_commit_type new |
|
} |
|
} |
|
}
|
|
|