 f6576f4c0c
			
		
	
	f6576f4c0c
	
	
	
		
			
			* git://repo.or.cz/git-gui: (27 commits)
  git-gui: Update German translation.
  git-gui: Do not munge conflict marker lines in a normal diff
  git-gui: Add a simple implementation of SSH_ASKPASS.
  git-gui: Add a dialog that shows the OpenSSH public key.
  git-gui: Mark-up strings in show_{other,unmerged}_diff() for localization
  git-gui: Show a round number of bytes of large untracked text files
  git-gui: Fix the blame viewer destroy handler.
  git-gui: Add a search command to the blame viewer.
  git-gui: Fix the blame window shape.
  git-gui: Fix switch statement in lib/merge.tcl
  git-gui: Fix fetching from remotes when adding them
  git-gui: Fix removing non-pushable remotes
  git-gui: Make input boxes in init/clone/open dialogs consistent
  git-gui: Avoid using the term URL when specifying repositories
  git-gui: gui.autoexplore makes explorer to pop up automatically after picking
  git-gui: Add Explore Working Copy to the Repository menu
  git-gui: Use git web--browser for web browsing
  git-gui: mkdir -p when initializing new remote repository
  git-gui: Add support for removing remotes
  git-gui: Add support for adding remotes
  ...
		
	
		
			
				
	
	
		
			453 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Tcl
		
	
	
	
	
	
			
		
		
	
	
			453 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Tcl
		
	
	
	
	
	
| # git-gui index (add/remove) support
 | |
| # Copyright (C) 2006, 2007 Shawn Pearce
 | |
| 
 | |
| proc _delete_indexlock {} {
 | |
| 	if {[catch {file delete -- [gitdir index.lock]} err]} {
 | |
| 		error_popup [strcat [mc "Unable to unlock the index."] "\n\n$err"]
 | |
| 	}
 | |
| }
 | |
| 
 | |
| proc _close_updateindex {fd after} {
 | |
| 	fconfigure $fd -blocking 1
 | |
| 	if {[catch {close $fd} err]} {
 | |
| 		set w .indexfried
 | |
| 		toplevel $w
 | |
| 		wm title $w [strcat "[appname] ([reponame]): " [mc "Index Error"]]
 | |
| 		wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
 | |
| 		pack [label $w.msg \
 | |
| 			-justify left \
 | |
| 			-anchor w \
 | |
| 			-text [strcat \
 | |
| 				[mc "Updating the Git index failed.  A rescan will be automatically started to resynchronize git-gui."] \
 | |
| 				"\n\n$err"] \
 | |
| 			] -anchor w
 | |
| 
 | |
| 		frame $w.buttons
 | |
| 		button $w.buttons.continue \
 | |
| 			-text [mc "Continue"] \
 | |
| 			-command [list destroy $w]
 | |
| 		pack $w.buttons.continue -side right -padx 5
 | |
| 		button $w.buttons.unlock \
 | |
| 			-text [mc "Unlock Index"] \
 | |
| 			-command "destroy $w; _delete_indexlock"
 | |
| 		pack $w.buttons.unlock -side right
 | |
| 		pack $w.buttons -side bottom -fill x -pady 10 -padx 10
 | |
| 
 | |
| 		wm protocol $w WM_DELETE_WINDOW update
 | |
| 		bind $w.buttons.continue <Visibility> "
 | |
| 			grab $w
 | |
| 			focus $w.buttons.continue
 | |
| 		"
 | |
| 		tkwait window $w
 | |
| 
 | |
| 		$::main_status stop
 | |
| 		unlock_index
 | |
| 		rescan $after 0
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	$::main_status stop
 | |
| 	unlock_index
 | |
| 	uplevel #0 $after
 | |
| }
 | |
| 
 | |
| proc update_indexinfo {msg pathList after} {
 | |
| 	global update_index_cp
 | |
| 
 | |
| 	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}
 | |
| 
 | |
| 	$::main_status start $msg [mc "files"]
 | |
| 	set fd [git_write update-index -z --index-info]
 | |
| 	fconfigure $fd \
 | |
| 		-blocking 0 \
 | |
| 		-buffering full \
 | |
| 		-buffersize 512 \
 | |
| 		-encoding binary \
 | |
| 		-translation binary
 | |
| 	fileevent $fd writable [list \
 | |
| 		write_update_indexinfo \
 | |
| 		$fd \
 | |
| 		$pathList \
 | |
| 		$totalCnt \
 | |
| 		$batch \
 | |
| 		$after \
 | |
| 		]
 | |
| }
 | |
| 
 | |
| proc write_update_indexinfo {fd pathList totalCnt batch after} {
 | |
| 	global update_index_cp
 | |
| 	global file_states current_diff_path
 | |
| 
 | |
| 	if {$update_index_cp >= $totalCnt} {
 | |
| 		_close_updateindex $fd $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}
 | |
| 		T_ {set new _T}
 | |
| 		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
 | |
| 	}
 | |
| 
 | |
| 	$::main_status update $update_index_cp $totalCnt
 | |
| }
 | |
| 
 | |
| proc update_index {msg pathList after} {
 | |
| 	global update_index_cp
 | |
| 
 | |
| 	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}
 | |
| 
 | |
| 	$::main_status start $msg [mc "files"]
 | |
| 	set fd [git_write update-index --add --remove -z --stdin]
 | |
| 	fconfigure $fd \
 | |
| 		-blocking 0 \
 | |
| 		-buffering full \
 | |
| 		-buffersize 512 \
 | |
| 		-encoding binary \
 | |
| 		-translation binary
 | |
| 	fileevent $fd writable [list \
 | |
| 		write_update_index \
 | |
| 		$fd \
 | |
| 		$pathList \
 | |
| 		$totalCnt \
 | |
| 		$batch \
 | |
| 		$after \
 | |
| 		]
 | |
| }
 | |
| 
 | |
| proc write_update_index {fd pathList totalCnt batch after} {
 | |
| 	global update_index_cp
 | |
| 	global file_states current_diff_path
 | |
| 
 | |
| 	if {$update_index_cp >= $totalCnt} {
 | |
| 		_close_updateindex $fd $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_}
 | |
| 		_T {set new T_}
 | |
| 		_U -
 | |
| 		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
 | |
| 	}
 | |
| 
 | |
| 	$::main_status update $update_index_cp $totalCnt
 | |
| }
 | |
| 
 | |
| proc checkout_index {msg pathList after} {
 | |
| 	global update_index_cp
 | |
| 
 | |
| 	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}
 | |
| 
 | |
| 	$::main_status start $msg [mc "files"]
 | |
| 	set fd [git_write checkout-index \
 | |
| 		--index \
 | |
| 		--quiet \
 | |
| 		--force \
 | |
| 		-z \
 | |
| 		--stdin \
 | |
| 		]
 | |
| 	fconfigure $fd \
 | |
| 		-blocking 0 \
 | |
| 		-buffering full \
 | |
| 		-buffersize 512 \
 | |
| 		-encoding binary \
 | |
| 		-translation binary
 | |
| 	fileevent $fd writable [list \
 | |
| 		write_checkout_index \
 | |
| 		$fd \
 | |
| 		$pathList \
 | |
| 		$totalCnt \
 | |
| 		$batch \
 | |
| 		$after \
 | |
| 		]
 | |
| }
 | |
| 
 | |
| proc write_checkout_index {fd pathList totalCnt batch after} {
 | |
| 	global update_index_cp
 | |
| 	global file_states current_diff_path
 | |
| 
 | |
| 	if {$update_index_cp >= $totalCnt} {
 | |
| 		_close_updateindex $fd $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 -
 | |
| 		?T -
 | |
| 		?D {
 | |
| 			puts -nonewline $fd "[encoding convertto $path]\0"
 | |
| 			display_file $path ?_
 | |
| 		}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	$::main_status update $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? -
 | |
| 		T_ -
 | |
| 		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 [list ui_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 \
 | |
| 			[mc "Unstaging %s from commit" [short_path $current_diff_path]] \
 | |
| 			[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] {
 | |
| 		_U -
 | |
| 		U? {
 | |
| 			if {$path eq $current_diff_path} {
 | |
| 				unlock_index
 | |
| 				merge_stage_workdir $path
 | |
| 				return
 | |
| 			}
 | |
| 		}
 | |
| 		_O -
 | |
| 		?M -
 | |
| 		?D -
 | |
| 		?T {
 | |
| 			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 {ui_status [mc "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 \
 | |
| 			[mc "Adding %s" [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 -
 | |
| 		?T -
 | |
| 		?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 -
 | |
| 		?T -
 | |
| 		?D {
 | |
| 			lappend pathList $path
 | |
| 			if {$path eq $current_diff_path} {
 | |
| 				set after {reshow_diff;}
 | |
| 			}
 | |
| 		}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 
 | |
| 	# Split question between singular and plural cases, because
 | |
| 	# such distinction is needed in some languages. Previously, the
 | |
| 	# code used "Revert changes in" for both, but that can't work
 | |
| 	# in languages where 'in' must be combined with word from
 | |
| 	# rest of string (in diffrent way for both cases of course).
 | |
| 	#
 | |
| 	# FIXME: Unfortunately, even that isn't enough in some languages
 | |
| 	# as they have quite complex plural-form rules. Unfortunately,
 | |
| 	# msgcat doesn't seem to support that kind of string translation.
 | |
| 	#
 | |
| 	set n [llength $pathList]
 | |
| 	if {$n == 0} {
 | |
| 		unlock_index
 | |
| 		return
 | |
| 	} elseif {$n == 1} {
 | |
| 		set query [mc "Revert changes in file %s?" [short_path [lindex $pathList]]]
 | |
| 	} else {
 | |
| 		set query [mc "Revert changes in these %i files?" $n]
 | |
| 	}
 | |
| 
 | |
| 	set reply [tk_dialog \
 | |
| 		.confirm_revert \
 | |
| 		"[appname] ([reponame])" \
 | |
| 		"$query
 | |
| 
 | |
| [mc "Any unstaged changes will be permanently lost by the revert."]" \
 | |
| 		question \
 | |
| 		1 \
 | |
| 		[mc "Do Nothing"] \
 | |
| 		[mc "Revert Changes"] \
 | |
| 		]
 | |
| 	if {$reply == 1} {
 | |
| 		checkout_index \
 | |
| 			$txt \
 | |
| 			$pathList \
 | |
| 			[concat $after [list ui_ready]]
 | |
| 	} else {
 | |
| 		unlock_index
 | |
| 	}
 | |
| }
 | |
| 
 | |
| proc do_revert_selection {} {
 | |
| 	global current_diff_path selected_paths
 | |
| 
 | |
| 	if {[array size selected_paths] > 0} {
 | |
| 		revert_helper \
 | |
| 			[mc "Reverting selected files"] \
 | |
| 			[array names selected_paths]
 | |
| 	} elseif {$current_diff_path ne {}} {
 | |
| 		revert_helper \
 | |
| 			[mc "Reverting %s" [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
 | |
| 		}
 | |
| 	}
 | |
| }
 |