 5f5dbd719d
			
		
	
	5f5dbd719d
	
	
	
		
			
			* 'master' of git://repo.or.cz/git-gui: git-gui: Use vi-like keys in merge dialog git-gui: Include commit id/subject in merge choices git-gui: Show all possible branches for merge git-gui: Move merge support into a namespace git-gui: Allow vi keys to scroll the diff/blame regions git-gui: Move console procs into their own namespace git-gui: Refactor into multiple files to save my sanity git-gui: Track our own embedded values and rebuild when they change git-gui: Refactor to use our git proc more often git-gui: Use option database defaults to set the font git-gui: Cleanup common font handling for font_ui git-gui: Correct line wrapping for too many branch message git-gui: Warn users before making an octopus merge git-gui: Include the subject in the status bar after commit Also perform an evil merge change to update Git's main Makefile to pass the proper options down into git-gui now that it depends on reasonable values for 'sharedir' and 'TCL_PATH'. Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
		
			
				
	
	
		
			573 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Tcl
		
	
	
	
	
	
			
		
		
	
	
			573 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Tcl
		
	
	
	
	
	
| # git-gui branch (create/delete) support
 | |
| # Copyright (C) 2006, 2007 Shawn Pearce
 | |
| 
 | |
| proc load_all_heads {} {
 | |
| 	global all_heads
 | |
| 
 | |
| 	set all_heads [list]
 | |
| 	set fd [open "| git for-each-ref --format=%(refname) refs/heads" r]
 | |
| 	while {[gets $fd line] > 0} {
 | |
| 		if {[is_tracking_branch $line]} continue
 | |
| 		if {![regsub ^refs/heads/ $line {} name]} continue
 | |
| 		lappend all_heads $name
 | |
| 	}
 | |
| 	close $fd
 | |
| 
 | |
| 	set all_heads [lsort $all_heads]
 | |
| }
 | |
| 
 | |
| proc load_all_tags {} {
 | |
| 	set all_tags [list]
 | |
| 	set fd [open "| git for-each-ref --format=%(refname) refs/tags" r]
 | |
| 	while {[gets $fd line] > 0} {
 | |
| 		if {![regsub ^refs/tags/ $line {} name]} continue
 | |
| 		lappend all_tags $name
 | |
| 	}
 | |
| 	close $fd
 | |
| 
 | |
| 	return [lsort $all_tags]
 | |
| }
 | |
| 
 | |
| proc populate_branch_menu {} {
 | |
| 	global all_heads disable_on_lock
 | |
| 
 | |
| 	set m .mbar.branch
 | |
| 	set last [$m index last]
 | |
| 	for {set i 0} {$i <= $last} {incr i} {
 | |
| 		if {[$m type $i] eq {separator}} {
 | |
| 			$m delete $i last
 | |
| 			set new_dol [list]
 | |
| 			foreach a $disable_on_lock {
 | |
| 				if {[lindex $a 0] ne $m || [lindex $a 2] < $i} {
 | |
| 					lappend new_dol $a
 | |
| 				}
 | |
| 			}
 | |
| 			set disable_on_lock $new_dol
 | |
| 			break
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if {$all_heads ne {}} {
 | |
| 		$m add separator
 | |
| 	}
 | |
| 	foreach b $all_heads {
 | |
| 		$m add radiobutton \
 | |
| 			-label $b \
 | |
| 			-command [list switch_branch $b] \
 | |
| 			-variable current_branch \
 | |
| 			-value $b
 | |
| 		lappend disable_on_lock \
 | |
| 			[list $m entryconf [$m index last] -state]
 | |
| 	}
 | |
| }
 | |
| 
 | |
| proc do_create_branch_action {w} {
 | |
| 	global all_heads null_sha1 repo_config
 | |
| 	global create_branch_checkout create_branch_revtype
 | |
| 	global create_branch_head create_branch_trackinghead
 | |
| 	global create_branch_name create_branch_revexp
 | |
| 	global create_branch_tag
 | |
| 
 | |
| 	set newbranch $create_branch_name
 | |
| 	if {$newbranch eq {}
 | |
| 		|| $newbranch eq $repo_config(gui.newbranchtemplate)} {
 | |
| 		tk_messageBox \
 | |
| 			-icon error \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message "Please supply a branch name."
 | |
| 		focus $w.desc.name_t
 | |
| 		return
 | |
| 	}
 | |
| 	if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} {
 | |
| 		tk_messageBox \
 | |
| 			-icon error \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message "Branch '$newbranch' already exists."
 | |
| 		focus $w.desc.name_t
 | |
| 		return
 | |
| 	}
 | |
| 	if {[catch {git check-ref-format "heads/$newbranch"}]} {
 | |
| 		tk_messageBox \
 | |
| 			-icon error \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message "We do not like '$newbranch' as a branch name."
 | |
| 		focus $w.desc.name_t
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	set rev {}
 | |
| 	switch -- $create_branch_revtype {
 | |
| 	head {set rev $create_branch_head}
 | |
| 	tracking {set rev $create_branch_trackinghead}
 | |
| 	tag {set rev $create_branch_tag}
 | |
| 	expression {set rev $create_branch_revexp}
 | |
| 	}
 | |
| 	if {[catch {set cmt [git rev-parse --verify "${rev}^0"]}]} {
 | |
| 		tk_messageBox \
 | |
| 			-icon error \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message "Invalid starting revision: $rev"
 | |
| 		return
 | |
| 	}
 | |
| 	if {[catch {
 | |
| 			git update-ref \
 | |
| 				-m "branch: Created from $rev" \
 | |
| 				"refs/heads/$newbranch" \
 | |
| 				$cmt \
 | |
| 				$null_sha1
 | |
| 		} err]} {
 | |
| 		tk_messageBox \
 | |
| 			-icon error \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message "Failed to create '$newbranch'.\n\n$err"
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	lappend all_heads $newbranch
 | |
| 	set all_heads [lsort $all_heads]
 | |
| 	populate_branch_menu
 | |
| 	destroy $w
 | |
| 	if {$create_branch_checkout} {
 | |
| 		switch_branch $newbranch
 | |
| 	}
 | |
| }
 | |
| 
 | |
| proc radio_selector {varname value args} {
 | |
| 	upvar #0 $varname var
 | |
| 	set var $value
 | |
| }
 | |
| 
 | |
| trace add variable create_branch_head write \
 | |
| 	[list radio_selector create_branch_revtype head]
 | |
| trace add variable create_branch_trackinghead write \
 | |
| 	[list radio_selector create_branch_revtype tracking]
 | |
| trace add variable create_branch_tag write \
 | |
| 	[list radio_selector create_branch_revtype tag]
 | |
| 
 | |
| trace add variable delete_branch_head write \
 | |
| 	[list radio_selector delete_branch_checktype head]
 | |
| trace add variable delete_branch_trackinghead write \
 | |
| 	[list radio_selector delete_branch_checktype tracking]
 | |
| 
 | |
| proc do_create_branch {} {
 | |
| 	global all_heads current_branch repo_config
 | |
| 	global create_branch_checkout create_branch_revtype
 | |
| 	global create_branch_head create_branch_trackinghead
 | |
| 	global create_branch_name create_branch_revexp
 | |
| 	global create_branch_tag
 | |
| 
 | |
| 	set w .branch_editor
 | |
| 	toplevel $w
 | |
| 	wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
 | |
| 
 | |
| 	label $w.header -text {Create New Branch} \
 | |
| 		-font font_uibold
 | |
| 	pack $w.header -side top -fill x
 | |
| 
 | |
| 	frame $w.buttons
 | |
| 	button $w.buttons.create -text Create \
 | |
| 		-default active \
 | |
| 		-command [list do_create_branch_action $w]
 | |
| 	pack $w.buttons.create -side right
 | |
| 	button $w.buttons.cancel -text {Cancel} \
 | |
| 		-command [list destroy $w]
 | |
| 	pack $w.buttons.cancel -side right -padx 5
 | |
| 	pack $w.buttons -side bottom -fill x -pady 10 -padx 10
 | |
| 
 | |
| 	labelframe $w.desc -text {Branch Description}
 | |
| 	label $w.desc.name_l -text {Name:}
 | |
| 	entry $w.desc.name_t \
 | |
| 		-borderwidth 1 \
 | |
| 		-relief sunken \
 | |
| 		-width 40 \
 | |
| 		-textvariable create_branch_name \
 | |
| 		-validate key \
 | |
| 		-validatecommand {
 | |
| 			if {%d == 1 && [regexp {[~^:?*\[\0- ]} %S]} {return 0}
 | |
| 			return 1
 | |
| 		}
 | |
| 	grid $w.desc.name_l $w.desc.name_t -sticky we -padx {0 5}
 | |
| 	grid columnconfigure $w.desc 1 -weight 1
 | |
| 	pack $w.desc -anchor nw -fill x -pady 5 -padx 5
 | |
| 
 | |
| 	labelframe $w.from -text {Starting Revision}
 | |
| 	radiobutton $w.from.head_r \
 | |
| 		-text {Local Branch:} \
 | |
| 		-value head \
 | |
| 		-variable create_branch_revtype
 | |
| 	eval tk_optionMenu $w.from.head_m create_branch_head $all_heads
 | |
| 	grid $w.from.head_r $w.from.head_m -sticky w
 | |
| 	set all_trackings [all_tracking_branches]
 | |
| 	if {$all_trackings ne {}} {
 | |
| 		set create_branch_trackinghead [lindex $all_trackings 0]
 | |
| 		radiobutton $w.from.tracking_r \
 | |
| 			-text {Tracking Branch:} \
 | |
| 			-value tracking \
 | |
| 			-variable create_branch_revtype
 | |
| 		eval tk_optionMenu $w.from.tracking_m \
 | |
| 			create_branch_trackinghead \
 | |
| 			$all_trackings
 | |
| 		grid $w.from.tracking_r $w.from.tracking_m -sticky w
 | |
| 	}
 | |
| 	set all_tags [load_all_tags]
 | |
| 	if {$all_tags ne {}} {
 | |
| 		set create_branch_tag [lindex $all_tags 0]
 | |
| 		radiobutton $w.from.tag_r \
 | |
| 			-text {Tag:} \
 | |
| 			-value tag \
 | |
| 			-variable create_branch_revtype
 | |
| 		eval tk_optionMenu $w.from.tag_m create_branch_tag $all_tags
 | |
| 		grid $w.from.tag_r $w.from.tag_m -sticky w
 | |
| 	}
 | |
| 	radiobutton $w.from.exp_r \
 | |
| 		-text {Revision Expression:} \
 | |
| 		-value expression \
 | |
| 		-variable create_branch_revtype
 | |
| 	entry $w.from.exp_t \
 | |
| 		-borderwidth 1 \
 | |
| 		-relief sunken \
 | |
| 		-width 50 \
 | |
| 		-textvariable create_branch_revexp \
 | |
| 		-validate key \
 | |
| 		-validatecommand {
 | |
| 			if {%d == 1 && [regexp {\s} %S]} {return 0}
 | |
| 			if {%d == 1 && [string length %S] > 0} {
 | |
| 				set create_branch_revtype expression
 | |
| 			}
 | |
| 			return 1
 | |
| 		}
 | |
| 	grid $w.from.exp_r $w.from.exp_t -sticky we -padx {0 5}
 | |
| 	grid columnconfigure $w.from 1 -weight 1
 | |
| 	pack $w.from -anchor nw -fill x -pady 5 -padx 5
 | |
| 
 | |
| 	labelframe $w.postActions -text {Post Creation Actions}
 | |
| 	checkbutton $w.postActions.checkout \
 | |
| 		-text {Checkout after creation} \
 | |
| 		-variable create_branch_checkout
 | |
| 	pack $w.postActions.checkout -anchor nw
 | |
| 	pack $w.postActions -anchor nw -fill x -pady 5 -padx 5
 | |
| 
 | |
| 	set create_branch_checkout 1
 | |
| 	set create_branch_head $current_branch
 | |
| 	set create_branch_revtype head
 | |
| 	set create_branch_name $repo_config(gui.newbranchtemplate)
 | |
| 	set create_branch_revexp {}
 | |
| 
 | |
| 	bind $w <Visibility> "
 | |
| 		grab $w
 | |
| 		$w.desc.name_t icursor end
 | |
| 		focus $w.desc.name_t
 | |
| 	"
 | |
| 	bind $w <Key-Escape> "destroy $w"
 | |
| 	bind $w <Key-Return> "do_create_branch_action $w;break"
 | |
| 	wm title $w "[appname] ([reponame]): Create Branch"
 | |
| 	tkwait window $w
 | |
| }
 | |
| 
 | |
| proc do_delete_branch_action {w} {
 | |
| 	global all_heads
 | |
| 	global delete_branch_checktype delete_branch_head delete_branch_trackinghead
 | |
| 
 | |
| 	set check_rev {}
 | |
| 	switch -- $delete_branch_checktype {
 | |
| 	head {set check_rev $delete_branch_head}
 | |
| 	tracking {set check_rev $delete_branch_trackinghead}
 | |
| 	always {set check_rev {:none}}
 | |
| 	}
 | |
| 	if {$check_rev eq {:none}} {
 | |
| 		set check_cmt {}
 | |
| 	} elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} {
 | |
| 		tk_messageBox \
 | |
| 			-icon error \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message "Invalid check revision: $check_rev"
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	set to_delete [list]
 | |
| 	set not_merged [list]
 | |
| 	foreach i [$w.list.l curselection] {
 | |
| 		set b [$w.list.l get $i]
 | |
| 		if {[catch {set o [git rev-parse --verify $b]}]} continue
 | |
| 		if {$check_cmt ne {}} {
 | |
| 			if {$b eq $check_rev} continue
 | |
| 			if {[catch {set m [git merge-base $o $check_cmt]}]} continue
 | |
| 			if {$o ne $m} {
 | |
| 				lappend not_merged $b
 | |
| 				continue
 | |
| 			}
 | |
| 		}
 | |
| 		lappend to_delete [list $b $o]
 | |
| 	}
 | |
| 	if {$not_merged ne {}} {
 | |
| 		set msg "The following branches are not completely merged into $check_rev:
 | |
| 
 | |
|  - [join $not_merged "\n - "]"
 | |
| 		tk_messageBox \
 | |
| 			-icon info \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message $msg
 | |
| 	}
 | |
| 	if {$to_delete eq {}} return
 | |
| 	if {$delete_branch_checktype eq {always}} {
 | |
| 		set msg {Recovering deleted branches is difficult.
 | |
| 
 | |
| Delete the selected branches?}
 | |
| 		if {[tk_messageBox \
 | |
| 			-icon warning \
 | |
| 			-type yesno \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message $msg] ne yes} {
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	set failed {}
 | |
| 	foreach i $to_delete {
 | |
| 		set b [lindex $i 0]
 | |
| 		set o [lindex $i 1]
 | |
| 		if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
 | |
| 			append failed " - $b: $err\n"
 | |
| 		} else {
 | |
| 			set x [lsearch -sorted -exact $all_heads $b]
 | |
| 			if {$x >= 0} {
 | |
| 				set all_heads [lreplace $all_heads $x $x]
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if {$failed ne {}} {
 | |
| 		tk_messageBox \
 | |
| 			-icon error \
 | |
| 			-type ok \
 | |
| 			-title [wm title $w] \
 | |
| 			-parent $w \
 | |
| 			-message "Failed to delete branches:\n$failed"
 | |
| 	}
 | |
| 
 | |
| 	set all_heads [lsort $all_heads]
 | |
| 	populate_branch_menu
 | |
| 	destroy $w
 | |
| }
 | |
| 
 | |
| proc do_delete_branch {} {
 | |
| 	global all_heads tracking_branches current_branch
 | |
| 	global delete_branch_checktype delete_branch_head delete_branch_trackinghead
 | |
| 
 | |
| 	set w .branch_editor
 | |
| 	toplevel $w
 | |
| 	wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
 | |
| 
 | |
| 	label $w.header -text {Delete Local Branch} \
 | |
| 		-font font_uibold
 | |
| 	pack $w.header -side top -fill x
 | |
| 
 | |
| 	frame $w.buttons
 | |
| 	button $w.buttons.create -text Delete \
 | |
| 		-command [list do_delete_branch_action $w]
 | |
| 	pack $w.buttons.create -side right
 | |
| 	button $w.buttons.cancel -text {Cancel} \
 | |
| 		-command [list destroy $w]
 | |
| 	pack $w.buttons.cancel -side right -padx 5
 | |
| 	pack $w.buttons -side bottom -fill x -pady 10 -padx 10
 | |
| 
 | |
| 	labelframe $w.list -text {Local Branches}
 | |
| 	listbox $w.list.l \
 | |
| 		-height 10 \
 | |
| 		-width 70 \
 | |
| 		-selectmode extended \
 | |
| 		-yscrollcommand [list $w.list.sby set]
 | |
| 	foreach h $all_heads {
 | |
| 		if {$h ne $current_branch} {
 | |
| 			$w.list.l insert end $h
 | |
| 		}
 | |
| 	}
 | |
| 	scrollbar $w.list.sby -command [list $w.list.l yview]
 | |
| 	pack $w.list.sby -side right -fill y
 | |
| 	pack $w.list.l -side left -fill both -expand 1
 | |
| 	pack $w.list -fill both -expand 1 -pady 5 -padx 5
 | |
| 
 | |
| 	labelframe $w.validate -text {Delete Only If}
 | |
| 	radiobutton $w.validate.head_r \
 | |
| 		-text {Merged Into Local Branch:} \
 | |
| 		-value head \
 | |
| 		-variable delete_branch_checktype
 | |
| 	eval tk_optionMenu $w.validate.head_m delete_branch_head $all_heads
 | |
| 	grid $w.validate.head_r $w.validate.head_m -sticky w
 | |
| 	set all_trackings [all_tracking_branches]
 | |
| 	if {$all_trackings ne {}} {
 | |
| 		set delete_branch_trackinghead [lindex $all_trackings 0]
 | |
| 		radiobutton $w.validate.tracking_r \
 | |
| 			-text {Merged Into Tracking Branch:} \
 | |
| 			-value tracking \
 | |
| 			-variable delete_branch_checktype
 | |
| 		eval tk_optionMenu $w.validate.tracking_m \
 | |
| 			delete_branch_trackinghead \
 | |
| 			$all_trackings
 | |
| 		grid $w.validate.tracking_r $w.validate.tracking_m -sticky w
 | |
| 	}
 | |
| 	radiobutton $w.validate.always_r \
 | |
| 		-text {Always (Do not perform merge checks)} \
 | |
| 		-value always \
 | |
| 		-variable delete_branch_checktype
 | |
| 	grid $w.validate.always_r -columnspan 2 -sticky w
 | |
| 	grid columnconfigure $w.validate 1 -weight 1
 | |
| 	pack $w.validate -anchor nw -fill x -pady 5 -padx 5
 | |
| 
 | |
| 	set delete_branch_head $current_branch
 | |
| 	set delete_branch_checktype head
 | |
| 
 | |
| 	bind $w <Visibility> "grab $w; focus $w"
 | |
| 	bind $w <Key-Escape> "destroy $w"
 | |
| 	wm title $w "[appname] ([reponame]): Delete Branch"
 | |
| 	tkwait window $w
 | |
| }
 | |
| 
 | |
| proc switch_branch {new_branch} {
 | |
| 	global HEAD commit_type current_branch repo_config
 | |
| 
 | |
| 	if {![lock_index switch]} return
 | |
| 
 | |
| 	# -- Our in memory state should match the repository.
 | |
| 	#
 | |
| 	repository_state curType curHEAD curMERGE_HEAD
 | |
| 	if {[string match amend* $commit_type]
 | |
| 		&& $curType eq {normal}
 | |
| 		&& $curHEAD eq $HEAD} {
 | |
| 	} elseif {$commit_type ne $curType || $HEAD ne $curHEAD} {
 | |
| 		info_popup {Last scanned state does not match repository state.
 | |
| 
 | |
| Another Git program has modified this repository since the last scan.  A rescan must be performed before the current branch can be changed.
 | |
| 
 | |
| The rescan will be automatically started now.
 | |
| }
 | |
| 		unlock_index
 | |
| 		rescan {set ui_status_value {Ready.}}
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	# -- Don't do a pointless switch.
 | |
| 	#
 | |
| 	if {$current_branch eq $new_branch} {
 | |
| 		unlock_index
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	if {$repo_config(gui.trustmtime) eq {true}} {
 | |
| 		switch_branch_stage2 {} $new_branch
 | |
| 	} else {
 | |
| 		set ui_status_value {Refreshing file status...}
 | |
| 		set cmd [list git update-index]
 | |
| 		lappend cmd -q
 | |
| 		lappend cmd --unmerged
 | |
| 		lappend cmd --ignore-missing
 | |
| 		lappend cmd --refresh
 | |
| 		set fd_rf [open "| $cmd" r]
 | |
| 		fconfigure $fd_rf -blocking 0 -translation binary
 | |
| 		fileevent $fd_rf readable \
 | |
| 			[list switch_branch_stage2 $fd_rf $new_branch]
 | |
| 	}
 | |
| }
 | |
| 
 | |
| proc switch_branch_stage2 {fd_rf new_branch} {
 | |
| 	global ui_status_value HEAD
 | |
| 
 | |
| 	if {$fd_rf ne {}} {
 | |
| 		read $fd_rf
 | |
| 		if {![eof $fd_rf]} return
 | |
| 		close $fd_rf
 | |
| 	}
 | |
| 
 | |
| 	set ui_status_value "Updating working directory to '$new_branch'..."
 | |
| 	set cmd [list git read-tree]
 | |
| 	lappend cmd -m
 | |
| 	lappend cmd -u
 | |
| 	lappend cmd --exclude-per-directory=.gitignore
 | |
| 	lappend cmd $HEAD
 | |
| 	lappend cmd $new_branch
 | |
| 	set fd_rt [open "| $cmd" r]
 | |
| 	fconfigure $fd_rt -blocking 0 -translation binary
 | |
| 	fileevent $fd_rt readable \
 | |
| 		[list switch_branch_readtree_wait $fd_rt $new_branch]
 | |
| }
 | |
| 
 | |
| proc switch_branch_readtree_wait {fd_rt new_branch} {
 | |
| 	global selected_commit_type commit_type HEAD MERGE_HEAD PARENT
 | |
| 	global current_branch
 | |
| 	global ui_comm ui_status_value
 | |
| 
 | |
| 	# -- We never get interesting output on stdout; only stderr.
 | |
| 	#
 | |
| 	read $fd_rt
 | |
| 	fconfigure $fd_rt -blocking 1
 | |
| 	if {![eof $fd_rt]} {
 | |
| 		fconfigure $fd_rt -blocking 0
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	# -- The working directory wasn't in sync with the index and
 | |
| 	#    we'd have to overwrite something to make the switch. A
 | |
| 	#    merge is required.
 | |
| 	#
 | |
| 	if {[catch {close $fd_rt} err]} {
 | |
| 		regsub {^fatal: } $err {} err
 | |
| 		warn_popup "File level merge required.
 | |
| 
 | |
| $err
 | |
| 
 | |
| Staying on branch '$current_branch'."
 | |
| 		set ui_status_value "Aborted checkout of '$new_branch' (file level merging is required)."
 | |
| 		unlock_index
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	# -- Update the symbolic ref.  Core git doesn't even check for failure
 | |
| 	#    here, it Just Works(tm).  If it doesn't we are in some really ugly
 | |
| 	#    state that is difficult to recover from within git-gui.
 | |
| 	#
 | |
| 	if {[catch {git symbolic-ref HEAD "refs/heads/$new_branch"} err]} {
 | |
| 		error_popup "Failed to set current branch.
 | |
| 
 | |
| This working directory is only partially switched.  We successfully updated your files, but failed to update an internal Git file.
 | |
| 
 | |
| This should not have occurred.  [appname] will now close and give up.
 | |
| 
 | |
| $err"
 | |
| 		do_quit
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	# -- Update our repository state.  If we were previously in amend mode
 | |
| 	#    we need to toss the current buffer and do a full rescan to update
 | |
| 	#    our file lists.  If we weren't in amend mode our file lists are
 | |
| 	#    accurate and we can avoid the rescan.
 | |
| 	#
 | |
| 	unlock_index
 | |
| 	set selected_commit_type new
 | |
| 	if {[string match amend* $commit_type]} {
 | |
| 		$ui_comm delete 0.0 end
 | |
| 		$ui_comm edit reset
 | |
| 		$ui_comm edit modified false
 | |
| 		rescan {set ui_status_value "Checked out branch '$current_branch'."}
 | |
| 	} else {
 | |
| 		repository_state commit_type HEAD MERGE_HEAD
 | |
| 		set PARENT $HEAD
 | |
| 		set ui_status_value "Checked out branch '$current_branch'."
 | |
| 	}
 | |
| }
 |