diff options
Diffstat (limited to 'git-gui/lib/index.tcl')
| -rw-r--r-- | git-gui/lib/index.tcl | 409 | 
1 files changed, 409 insertions, 0 deletions
| diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl new file mode 100644 index 0000000000..42742850ee --- /dev/null +++ b/git-gui/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 +		} +	} +} | 
