summaryrefslogtreecommitdiff
path: root/lib/index.tcl
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2007-05-08 03:35:48 (GMT)
committerShawn O. Pearce <spearce@spearce.org>2007-05-08 03:35:48 (GMT)
commitf522c9b5ed367172f969397589ae3d686b867ac0 (patch)
tree61315e92a1cf8f5edb67181a4e22a724195babeb /lib/index.tcl
parentc6a5e4030320c934bca70471d04aa9e7d8e2cd67 (diff)
downloadgit-f522c9b5ed367172f969397589ae3d686b867ac0.zip
git-f522c9b5ed367172f969397589ae3d686b867ac0.tar.gz
git-f522c9b5ed367172f969397589ae3d686b867ac0.tar.bz2
git-gui: Refactor into multiple files to save my sanity
I'm finding it difficult to work with a 6,000+ line Tcl script and not go insane while looking for a particular block of code. Since most of the program is organized into different units of functionality and not all users will need all units immediately on startup we can improve things by splitting procs out into multiple files and let auto_load handle things for us. This should help not only to better organize the source, but it may also improve startup times for some users as the Tcl parser does not need to read as much script before it can show the UI. In many cases the user can avoid reading at least half of git-gui now. Unfortunately we now need a library directory in our runtime location. This is currently assumed to be $(sharedir)/git-gui/lib and its expected that the Makefile invoker will setup some sort of reasonable sharedir value for us, or let us assume its going to be $(gitexecdir)/../share. We now also require a tclsh (in TCL_PATH) to just run the Makefile, as we use tclsh to generate the tclIndex for our lib directory. I'm hoping this is not an unncessary burden on end-users who are building from source. I haven't really made any functionality changes here, this is just a huge migration of code from one file to many smaller files. All of the new changes are to setup the library path and install the library files. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'lib/index.tcl')
-rw-r--r--lib/index.tcl409
1 files changed, 409 insertions, 0 deletions
diff --git a/lib/index.tcl b/lib/index.tcl
new file mode 100644
index 0000000..4274285
--- /dev/null
+++ b/lib/index.tcl
@@ -0,0 +1,409 @@
+# 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
+ }
+ }
+}