diff options
Diffstat (limited to 'git-gui/lib')
| -rw-r--r-- | git-gui/lib/blame.tcl | 28 | ||||
| -rw-r--r-- | git-gui/lib/branch_rename.tcl | 2 | ||||
| -rw-r--r-- | git-gui/lib/browser.tcl | 2 | ||||
| -rw-r--r-- | git-gui/lib/choose_repository.tcl | 25 | ||||
| -rw-r--r-- | git-gui/lib/commit.tcl | 9 | ||||
| -rw-r--r-- | git-gui/lib/diff.tcl | 150 | ||||
| -rw-r--r-- | git-gui/lib/index.tcl | 10 | ||||
| -rw-r--r-- | git-gui/lib/merge.tcl | 2 | ||||
| -rw-r--r-- | git-gui/lib/mergetool.tcl | 101 | ||||
| -rw-r--r-- | git-gui/lib/option.tcl | 1 | ||||
| -rw-r--r-- | git-gui/lib/remote.tcl | 91 | ||||
| -rw-r--r-- | git-gui/lib/remote_branch_delete.tcl | 9 | ||||
| -rw-r--r-- | git-gui/lib/shortcut.tcl | 4 | ||||
| -rw-r--r-- | git-gui/lib/status_bar.tcl | 1 | ||||
| -rw-r--r-- | git-gui/lib/transport.tcl | 34 | ||||
| -rw-r--r-- | git-gui/lib/win32.tcl | 4 | 
16 files changed, 342 insertions, 131 deletions
| diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index 786b50b8c2..61e358f960 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -449,11 +449,35 @@ method _load {jump} {  	$status show [mc "Reading %s..." "$commit:[escape_path $path]"]  	$w_path conf -text [escape_path $path] + +	set do_textconv 0 +	if {![is_config_false gui.textconv] && [git-version >= 1.7.2]} { +		set filter [gitattr $path diff set] +		set textconv [get_config [join [list diff $filter textconv] .]] +		if {$filter ne {set} && $textconv ne {}} { +			set do_textconv 1 +		} +	}  	if {$commit eq {}} { -		set fd [open $path r] +		if {$do_textconv ne 0} { +			# Run textconv with sh -c "..." to allow it to +			# contain command + arguments. On windows, just +			# call the filter command. +			if {![file executable [shellpath]]} { +				set fd [open |[linsert $textconv end $path] r] +			} else { +				set fd [open |[list [shellpath] -c "$textconv \"\$0\"" $path] r] +			} +		} else { +			set fd [open $path r] +		}  		fconfigure $fd -eofchar {}  	} else { -		set fd [git_read cat-file blob "$commit:$path"] +		if {$do_textconv ne 0} { +			set fd [git_read cat-file --textconv "$commit:$path"] +		} else { +			set fd [git_read cat-file blob "$commit:$path"] +		}  	}  	fconfigure $fd \  		-blocking 0 \ diff --git a/git-gui/lib/branch_rename.tcl b/git-gui/lib/branch_rename.tcl index 63988773ba..6e510ec2e3 100644 --- a/git-gui/lib/branch_rename.tcl +++ b/git-gui/lib/branch_rename.tcl @@ -53,7 +53,7 @@ constructor dialog {} {  			return 1  		} -	grid $w.rename.oldname_l $w.rename.oldname_m -sticky w  -padx {0 5} +	grid $w.rename.oldname_l $w.rename.oldname_m -sticky we -padx {0 5}  	grid $w.rename.newname_l $w.rename.newname_t -sticky we -padx {0 5}  	grid columnconfigure $w.rename 1 -weight 1  	pack $w.rename -anchor nw -fill x -pady 5 -padx 5 diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl index c2415729e0..a8c6223511 100644 --- a/git-gui/lib/browser.tcl +++ b/git-gui/lib/browser.tcl @@ -121,7 +121,7 @@ method _parent {} {  		if {$browser_stack eq {}} {  			regsub {:.*$} $browser_path {:} browser_path  		} else { -			regsub {/[^/]+$} $browser_path {} browser_path +			regsub {/[^/]+/$} $browser_path {/} browser_path  		}  		set browser_status [mc "Loading %s..." $browser_path]  		_ls $this [lindex $parent 0] [lindex $parent 1] diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl index 64f06748b6..657f7d5dc1 100644 --- a/git-gui/lib/choose_repository.tcl +++ b/git-gui/lib/choose_repository.tcl @@ -100,12 +100,17 @@ constructor pick {} {  	$opts insert end [mc "Clone Existing Repository"] link_clone  	$opts insert end "\n"  	if {$m_repo ne {}} { +		if {[tk windowingsystem] eq "win32"} { +			set key L +		} else { +			set key C +		}  		$m_repo add command \  			-command [cb _next clone] \ -			-accelerator $M1T-C \ +			-accelerator $M1T-$key \  			-label [mc "Clone..."] -		bind $top <$M1B-c> [cb _next clone] -		bind $top <$M1B-C> [cb _next clone] +		bind $top <$M1B-[string tolower $key]> [cb _next clone] +		bind $top <$M1B-[string toupper $key]> [cb _next clone]  	}  	$opts tag conf link_open -foreground blue -underline 1 @@ -209,14 +214,6 @@ constructor pick {} {  	}  } -proc _home {} { -	if {[catch {set h $::env(HOME)}] -		|| ![file isdirectory $h]} { -		set h . -	} -	return $h -} -  method _center {} {  	set nx [winfo reqwidth $top]  	set ny [winfo reqheight $top] @@ -415,7 +412,7 @@ method _new_local_path {} {  	if {$local_path ne {}} {  		set p [file dirname $local_path]  	} else { -		set p [_home] +		set p [pwd]  	}  	set p [tk_chooseDirectory \ @@ -536,7 +533,7 @@ method _open_origin {} {  	if {$origin_url ne {} && [file isdirectory $origin_url]} {  		set p $origin_url  	} else { -		set p [_home] +		set p [pwd]  	}  	set p [tk_chooseDirectory \ @@ -1037,7 +1034,7 @@ method _open_local_path {} {  	if {$local_path ne {}} {  		set p $local_path  	} else { -		set p [_home] +		set p [pwd]  	}  	set p [tk_chooseDirectory \ diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 7f459cd564..5ce46877bf 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -161,11 +161,12 @@ The rescan will be automatically started now.  	#  	set files_ready 0  	foreach path [array names file_states] { -		switch -glob -- [lindex $file_states($path) 0] { +		set s $file_states($path) +		switch -glob -- [lindex $s 0] {  		_? {continue}  		A? -  		D? - -		T_ - +		T? -  		M? {set files_ready 1}  		_U -  		U? { @@ -452,7 +453,11 @@ A rescan will be automatically started now.  		}  		AM -  		AD - +		AT - +		TM - +		TD -  		MM - +		MT -  		MD {  			set file_states($path) [list \  				_[string index $m 1] \ diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index ec8c11eeb7..cf8a95ec34 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -55,7 +55,7 @@ proc handle_empty_diff {} {  	set path $current_diff_path  	set s $file_states($path) -	if {[lindex $s 0] ne {_M}} return +	if {[lindex $s 0] ne {_M} || [has_textconv $path]} return  	# Prevent infinite rescan loops  	incr diff_empty_count @@ -122,22 +122,22 @@ proc show_unmerged_diff {cont_info} {  	if {$merge_stages(2) eq {}} {  		set is_conflict_diff 1  		lappend current_diff_queue \ -			[list [mc "LOCAL: deleted\nREMOTE:\n"] d======= \ +			[list [mc "LOCAL: deleted\nREMOTE:\n"] d= \  			    [list ":1:$current_diff_path" ":3:$current_diff_path"]]  	} elseif {$merge_stages(3) eq {}} {  		set is_conflict_diff 1  		lappend current_diff_queue \ -			[list [mc "REMOTE: deleted\nLOCAL:\n"] d======= \ +			[list [mc "REMOTE: deleted\nLOCAL:\n"] d= \  			    [list ":1:$current_diff_path" ":2:$current_diff_path"]]  	} elseif {[lindex $merge_stages(1) 0] eq {120000}  		|| [lindex $merge_stages(2) 0] eq {120000}  		|| [lindex $merge_stages(3) 0] eq {120000}} {  		set is_conflict_diff 1  		lappend current_diff_queue \ -			[list [mc "LOCAL:\n"] d======= \ +			[list [mc "LOCAL:\n"] d= \  			    [list ":1:$current_diff_path" ":2:$current_diff_path"]]  		lappend current_diff_queue \ -			[list [mc "REMOTE:\n"] d======= \ +			[list [mc "REMOTE:\n"] d= \  			    [list ":1:$current_diff_path" ":3:$current_diff_path"]]  	} else {  		start_show_diff $cont_info @@ -208,32 +208,32 @@ proc show_other_diff {path w m cont_info} {  			$ui_diff insert end [append \  				"* " \  				[mc "Git Repository (subproject)"] \ -				"\n"] d_@ +				"\n"] d_info  		} elseif {![catch {set type [exec file $path]}]} {  			set n [string length $path]  			if {[string equal -length $n $path $type]} {  				set type [string range $type $n end]  				regsub {^:?\s*} $type {} type  			} -			$ui_diff insert end "* $type\n" d_@ +			$ui_diff insert end "* $type\n" d_info  		}  		if {[string first "\0" $content] != -1} {  			$ui_diff insert end \  				[mc "* Binary file (not showing content)."] \ -				d_@ +				d_info  		} else {  			if {$sz > $max_sz} {  				$ui_diff insert end [mc \  "* Untracked file is %d bytes.  * Showing only first %d bytes. -" $sz $max_sz] d_@ +" $sz $max_sz] d_info  			}  			$ui_diff insert end $content  			if {$sz > $max_sz} {  				$ui_diff insert end [mc "  * Untracked file clipped here by %s.  * To see the entire file, use an external editor. -" [appname]] d_@ +" [appname]] d_info  			}  		}  		$ui_diff conf -state disabled @@ -253,6 +253,19 @@ proc show_other_diff {path w m cont_info} {  	}  } +proc get_conflict_marker_size {path} { +	set size 7 +	catch { +		set fd_rc [eval [list git_read check-attr "conflict-marker-size" -- $path]] +		set ret [gets $fd_rc line] +		close $fd_rc +		if {$ret > 0} { +			regexp {.*: conflict-marker-size: (\d+)$} $line line size +		} +	} +	return $size +} +  proc start_show_diff {cont_info {add_opts {}}} {  	global file_states file_lists  	global is_3way_diff is_submodule_diff diff_active repo_config @@ -268,6 +281,7 @@ proc start_show_diff {cont_info {add_opts {}}} {  	set is_submodule_diff 0  	set diff_active 1  	set current_diff_header {} +	set conflict_size [get_conflict_marker_size $path]  	set cmd [list]  	if {$w eq $ui_index} { @@ -280,6 +294,9 @@ proc start_show_diff {cont_info {add_opts {}}} {  			lappend cmd diff-files  		}  	} +	if {![is_config_false gui.textconv] && [git-version >= 1.6.1]} { +		lappend cmd --textconv +	}  	if {[string match {160000 *} [lindex $s 2]]  	 || [string match {160000 *} [lindex $s 3]]} { @@ -291,7 +308,7 @@ proc start_show_diff {cont_info {add_opts {}}} {  	}  	lappend cmd -p -	lappend cmd --no-color +	lappend cmd --color  	if {$repo_config(gui.diffcontext) >= 1} {  		lappend cmd "-U$repo_config(gui.diffcontext)"  	} @@ -326,10 +343,35 @@ proc start_show_diff {cont_info {add_opts {}}} {  		-blocking 0 \  		-encoding [get_path_encoding $path] \  		-translation lf -	fileevent $fd readable [list read_diff $fd $cont_info] +	fileevent $fd readable [list read_diff $fd $conflict_size $cont_info]  } -proc read_diff {fd cont_info} { +proc parse_color_line {line} { +	set start 0 +	set result "" +	set markup [list] +	set regexp {\033\[((?:\d+;)*\d+)?m} +	set need_reset 0 +	while {[regexp -indices -start $start $regexp $line match code]} { +		foreach {begin end} $match break +		append result [string range $line $start [expr {$begin - 1}]] +		set pos [string length $result] +		set col [eval [linsert $code 0 string range $line]] +		set start [incr end] +		if {$col eq "0" || $col eq ""} { +			if {!$need_reset} continue +			set need_reset 0 +		} else { +			set need_reset 1 +		} +		lappend markup $pos $col +	} +	append result [string range $line $start end] +	if {[llength $markup] < 4} {set markup {}} +	return [list $result $markup] +} + +proc read_diff {fd conflict_size cont_info} {  	global ui_diff diff_active is_submodule_diff  	global is_3way_diff is_conflict_diff current_diff_header  	global current_diff_queue @@ -337,37 +379,53 @@ proc read_diff {fd cont_info} {  	$ui_diff conf -state normal  	while {[gets $fd line] >= 0} { -		# -- Cleanup uninteresting diff header lines. +		foreach {line markup} [parse_color_line $line] break +		set line [string map {\033 ^} $line] + +		set tags {} + +		# -- Check for start of diff header. +		if {   [string match {diff --git *}      $line] +		    || [string match {diff --cc *}       $line] +		    || [string match {diff --combined *} $line]} { +			set ::current_diff_inheader 1 +		} + +		# -- Check for end of diff header (any hunk line will do this). +		# +		if {[regexp {^@@+ } $line]} {set ::current_diff_inheader 0} + +		# -- Automatically detect if this is a 3 way diff.  		# +		if {[string match {@@@ *} $line]} {set is_3way_diff 1} +  		if {$::current_diff_inheader} { + +			# -- These two lines stop a diff header and shouldn't be in there +			if {   [string match {Binary files * and * differ} $line] +			    || [regexp {^\* Unmerged path }                $line]} { +				set ::current_diff_inheader 0 +			} else { +				append current_diff_header $line "\n" +			} + +			# -- Cleanup uninteresting diff header lines. +			#  			if {   [string match {diff --git *}      $line]  			    || [string match {diff --cc *}       $line]  			    || [string match {diff --combined *} $line]  			    || [string match {--- *}             $line] -			    || [string match {+++ *}             $line]} { -				append current_diff_header $line "\n" +			    || [string match {+++ *}             $line] +			    || [string match {index *}           $line]} {  				continue  			} -		} -		if {[string match {index *} $line]} continue -		if {$line eq {deleted file mode 120000}} { -			set line "deleted symlink" -		} -		set ::current_diff_inheader 0 -		# -- Automatically detect if this is a 3 way diff. -		# -		if {[string match {@@@ *} $line]} {set is_3way_diff 1} +			# -- Name it symlink, not 120000 +			#    Note, that the original line is in $current_diff_header +			regsub {^(deleted|new) file mode 120000} $line {\1 symlink} line -		if {[string match {mode *} $line] -			|| [string match {new file *} $line] -			|| [regexp {^(old|new) mode *} $line] -			|| [string match {deleted file *} $line] -			|| [string match {deleted symlink} $line] -			|| [string match {Binary files * and * differ} $line] -			|| $line eq {\ No newline at end of file} -			|| [regexp {^\* Unmerged path } $line]} { -			set tags {} +		} elseif {   $line eq {\ No newline at end of file}} { +			# -- Handle some special lines  		} elseif {$is_3way_diff} {  			set op [string range $line 0 1]  			switch -- $op { @@ -379,7 +437,9 @@ proc read_diff {fd cont_info} {  			{- } {set tags d_-s}  			{--} {set tags d_--}  			{++} { -				if {[regexp {^\+\+([<>]{7} |={7})} $line _g op]} { +				set regexp [string map [list %conflict_size $conflict_size]\ +								{^\+\+([<>=]){%conflict_size}(?: |$)}] +				if {[regexp $regexp $line _g op]} {  					set is_conflict_diff 1  					set line [string replace $line 0 1 {  }]  					set tags d$op @@ -395,10 +455,10 @@ proc read_diff {fd cont_info} {  		} elseif {$is_submodule_diff} {  			if {$line == ""} continue  			if {[regexp {^Submodule } $line]} { -				set tags d_@ +				set tags d_info  			} elseif {[regexp {^\* } $line]} {  				set line [string replace $line 0 1 {Submodule }] -				set tags d_@ +				set tags d_info  			} else {  				set op [string range $line 0 2]  				switch -- $op { @@ -418,7 +478,9 @@ proc read_diff {fd cont_info} {  			{@} {set tags d_@}  			{-} {set tags d_-}  			{+} { -				if {[regexp {^\+([<>]{7} |={7})} $line _g op]} { +				set regexp [string map [list %conflict_size $conflict_size]\ +								{^\+([<>=]){%conflict_size}(?: |$)}] +				if {[regexp $regexp $line _g op]} {  					set is_conflict_diff 1  					set tags d$op  				} else { @@ -431,11 +493,23 @@ proc read_diff {fd cont_info} {  			}  			}  		} +		set mark [$ui_diff index "end - 1 line linestart"]  		$ui_diff insert end $line $tags  		if {[string index $line end] eq "\r"} {  			$ui_diff tag add d_cr {end - 2c}  		}  		$ui_diff insert end "\n" $tags + +		foreach {posbegin colbegin posend colend} $markup { +			set prefix clr +			foreach style [split $colbegin ";"] { +				if {$style eq "7"} {append prefix i; continue} +				if {$style < 30 || $style > 47} {continue} +				set a "$mark linestart + $posbegin chars" +				set b "$mark linestart + $posend chars" +				catch {$ui_diff tag add $prefix$style $a $b} +			} +		}  	}  	$ui_diff conf -state disabled diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index e9db0c4989..5d7bbf23ed 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl @@ -103,8 +103,11 @@ proc write_update_indexinfo {fd pathList totalCnt batch after} {  		set s $file_states($path)  		switch -glob -- [lindex $s 0] {  		A? {set new _O} -		M? {set new _M} +		MT - +		TM -  		T_ {set new _T} +		M? {set new _M} +		TD -  		D_ {set new _D}  		D? {set new _?}  		?? {continue} @@ -167,7 +170,10 @@ proc write_update_index {fd pathList totalCnt batch after} {  		AD {set new __}  		?D {set new D_}  		_O - +		AT -  		AM {set new A_} +		TM - +		MT -  		_T {set new T_}  		_U -  		U? { @@ -261,7 +267,7 @@ proc unstage_helper {txt paths} {  		switch -glob -- [lindex $file_states($path) 0] {  		A? -  		M? - -		T_ - +		T? -  		D? {  			lappend pathList $path  			if {$path eq $current_diff_path} { diff --git a/git-gui/lib/merge.tcl b/git-gui/lib/merge.tcl index 5cded2341c..460d32fa22 100644 --- a/git-gui/lib/merge.tcl +++ b/git-gui/lib/merge.tcl @@ -83,6 +83,7 @@ method _visualize {} {  method _start {} {  	global HEAD current_branch remote_url +	global _last_merged_branch  	set name [_rev $this]  	if {$name eq {}} { @@ -109,6 +110,7 @@ method _start {} {  	regsub ^refs/heads/ $branch {} branch  	puts $fh "$cmit\t\tbranch '$branch' of $remote"  	close $fh +	set _last_merged_branch $branch  	set cmd [list git]  	lappend cmd merge diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl index 3fe90e6970..3c8e73bceb 100644 --- a/git-gui/lib/mergetool.tcl +++ b/git-gui/lib/mergetool.tcl @@ -175,43 +175,56 @@ proc merge_resolve_tool2 {} {  	# Build the command line  	switch -- $tool { -	kdiff3 { +	araxis {  		if {$base_stage ne {}} { -			set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Base)" \ -				--L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE"] +			set cmdline [list "$merge_tool_path" -wait -merge -3 -a1 \ +				-title1:"'$MERGED (Base)'" -title2:"'$MERGED (Local)'" \ +				-title3:"'$MERGED (Remote)'" \ +				"$BASE" "$LOCAL" "$REMOTE" "$MERGED"]  		} else { -			set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Local)" \ -				--L2 "$MERGED (Remote)" -o "$MERGED" "$LOCAL" "$REMOTE"] +			set cmdline [list "$merge_tool_path" -wait -2 \ +				 -title1:"'$MERGED (Local)'" -title2:"'$MERGED (Remote)'" \ +				 "$LOCAL" "$REMOTE" "$MERGED"]  		}  	} -	tkdiff { +	bc3 {  		if {$base_stage ne {}} { -			set cmdline [list "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"] +			set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" "$BASE" -mergeoutput="$MERGED"]  		} else { -			set cmdline [list "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"] +			set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -mergeoutput="$MERGED"]  		}  	} -	meld { -		set cmdline [list "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"] +	ecmerge { +		if {$base_stage ne {}} { +			set cmdline [list "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"] +		} else { +			set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"] +		} +	} +	emerge { +		if {$base_stage ne {}} { +			set cmdline [list "$merge_tool_path" -f emerge-files-with-ancestor-command \ +					"$LOCAL" "$REMOTE" "$BASE" "$basename"] +		} else { +			set cmdline [list "$merge_tool_path" -f emerge-files-command \ +					"$LOCAL" "$REMOTE" "$basename"] +		}  	}  	gvimdiff {  		set cmdline [list "$merge_tool_path" -f "$LOCAL" "$MERGED" "$REMOTE"]  	} -	xxdiff { +	kdiff3 {  		if {$base_stage ne {}} { -			set cmdline [list "$merge_tool_path" -X --show-merged-pane \ -					    -R {Accel.SaveAsMerged: "Ctrl-S"} \ -					    -R {Accel.Search: "Ctrl+F"} \ -					    -R {Accel.SearchForward: "Ctrl-G"} \ -					    --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"] +			set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Base)" \ +				--L2 "$MERGED (Local)" --L3 "$MERGED (Remote)" -o "$MERGED" "$BASE" "$LOCAL" "$REMOTE"]  		} else { -			set cmdline [list "$merge_tool_path" -X --show-merged-pane \ -					    -R {Accel.SaveAsMerged: "Ctrl-S"} \ -					    -R {Accel.Search: "Ctrl+F"} \ -					    -R {Accel.SearchForward: "Ctrl-G"} \ -					    --merged-file "$MERGED" "$LOCAL" "$REMOTE"] +			set cmdline [list "$merge_tool_path" --auto --L1 "$MERGED (Local)" \ +				--L2 "$MERGED (Remote)" -o "$MERGED" "$LOCAL" "$REMOTE"]  		}  	} +	meld { +		set cmdline [list "$merge_tool_path" "$LOCAL" "$MERGED" "$REMOTE"] +	}  	opendiff {  		if {$base_stage ne {}} {  			set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED"] @@ -219,22 +232,20 @@ proc merge_resolve_tool2 {} {  			set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" -merge "$MERGED"]  		}  	} -	ecmerge { -		if {$base_stage ne {}} { -			set cmdline [list "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" --default --mode=merge3 --to="$MERGED"] -		} else { -			set cmdline [list "$merge_tool_path" "$LOCAL" "$REMOTE" --default --mode=merge2 --to="$MERGED"] -		} +	p4merge { +		set cmdline [list "$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED"]  	} -	emerge { +	tkdiff {  		if {$base_stage ne {}} { -			set cmdline [list "$merge_tool_path" -f emerge-files-with-ancestor-command \ -					"$LOCAL" "$REMOTE" "$BASE" "$basename"] +			set cmdline [list "$merge_tool_path" -a "$BASE" -o "$MERGED" "$LOCAL" "$REMOTE"]  		} else { -			set cmdline [list "$merge_tool_path" -f emerge-files-command \ -					"$LOCAL" "$REMOTE" "$basename"] +			set cmdline [list "$merge_tool_path" -o "$MERGED" "$LOCAL" "$REMOTE"]  		}  	} +	vimdiff { +		error_popup [mc "Not a GUI merge tool: '%s'" $tool] +		return +	}  	winmerge {  		if {$base_stage ne {}} {  			# This tool does not support 3-way merges. @@ -245,25 +256,21 @@ proc merge_resolve_tool2 {} {  				-dl "Theirs File" -dr "Mine File" "$REMOTE" "$LOCAL" "$MERGED"]  		}  	} -	araxis { +	xxdiff {  		if {$base_stage ne {}} { -			set cmdline [list "$merge_tool_path" -wait -merge -3 -a1 \ -				-title1:"'$MERGED (Base)'" -title2:"'$MERGED (Local)'" \ -				-title3:"'$MERGED (Remote)'" \ -				"$BASE" "$LOCAL" "$REMOTE" "$MERGED"] +			set cmdline [list "$merge_tool_path" -X --show-merged-pane \ +					    -R {Accel.SaveAsMerged: "Ctrl-S"} \ +					    -R {Accel.Search: "Ctrl+F"} \ +					    -R {Accel.SearchForward: "Ctrl-G"} \ +					    --merged-file "$MERGED" "$LOCAL" "$BASE" "$REMOTE"]  		} else { -			set cmdline [list "$merge_tool_path" -wait -2 \ -				 -title1:"'$MERGED (Local)'" -title2:"'$MERGED (Remote)'" \ -				 "$LOCAL" "$REMOTE" "$MERGED"] +			set cmdline [list "$merge_tool_path" -X --show-merged-pane \ +					    -R {Accel.SaveAsMerged: "Ctrl-S"} \ +					    -R {Accel.Search: "Ctrl+F"} \ +					    -R {Accel.SearchForward: "Ctrl-G"} \ +					    --merged-file "$MERGED" "$LOCAL" "$REMOTE"]  		}  	} -	p4merge { -		set cmdline [list "$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED"] -	} -	vimdiff { -		error_popup [mc "Not a GUI merge tool: '%s'" $tool] -		return -	}  	default {  		error_popup [mc "Unsupported merge tool '%s'" $tool]  		return diff --git a/git-gui/lib/option.tcl b/git-gui/lib/option.tcl index d4c5e45c8a..3807c8d283 100644 --- a/git-gui/lib/option.tcl +++ b/git-gui/lib/option.tcl @@ -148,6 +148,7 @@ proc do_options {} {  		{b gui.trustmtime  {mc "Trust File Modification Timestamps"}}  		{b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}}  		{b gui.matchtrackingbranch {mc "Match Tracking Branches"}} +		{b gui.textconv {mc "Use Textconv For Diffs and Blames"}}  		{b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}}  		{i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}  		{i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}} diff --git a/git-gui/lib/remote.tcl b/git-gui/lib/remote.tcl index b92b429cf7..5e4e7f4c83 100644 --- a/git-gui/lib/remote.tcl +++ b/git-gui/lib/remote.tcl @@ -157,22 +157,7 @@ proc add_fetch_entry {r} {  	}  	if {$enable} { -		if {![winfo exists $fetch_m]} { -			menu $remove_m -			$remote_m insert 0 cascade \ -				-label [mc "Remove Remote"] \ -				-menu $remove_m - -			menu $prune_m -			$remote_m insert 0 cascade \ -				-label [mc "Prune from"] \ -				-menu $prune_m - -			menu $fetch_m -			$remote_m insert 0 cascade \ -				-label [mc "Fetch from"] \ -				-menu $fetch_m -		} +		make_sure_remote_submenues_exist $remote_m  		$fetch_m add command \  			-label $r \ @@ -222,6 +207,70 @@ proc add_push_entry {r} {  	}  } +proc make_sure_remote_submenues_exist {remote_m} { +	set fetch_m $remote_m.fetch +	set prune_m $remote_m.prune +	set remove_m $remote_m.remove + +	if {![winfo exists $fetch_m]} { +		menu $remove_m +		$remote_m insert 0 cascade \ +			-label [mc "Remove Remote"] \ +			-menu $remove_m + +		menu $prune_m +		$remote_m insert 0 cascade \ +			-label [mc "Prune from"] \ +			-menu $prune_m + +		menu $fetch_m +		$remote_m insert 0 cascade \ +			-label [mc "Fetch from"] \ +			-menu $fetch_m +	} +} + +proc update_all_remotes_menu_entry {} { +	global all_remotes + +	if {[git-version < 1.6.6]} { return } + +	set have_remote 0 +	foreach r $all_remotes { +		incr have_remote +	} + +	set remote_m .mbar.remote +	set fetch_m $remote_m.fetch +	set prune_m $remote_m.prune +	if {$have_remote > 1} { +		make_sure_remote_submenues_exist $remote_m +		if {[$fetch_m entrycget end -label] ne "All"} { + +			$fetch_m insert end separator +			$fetch_m insert end command \ +				-label "All" \ +				-command fetch_from_all + +			$prune_m insert end separator +			$prune_m insert end command \ +				-label "All" \ +				-command prune_from_all +		} +	} else { +		if {[winfo exists $fetch_m]} { +			if {[$fetch_m entrycget end -label] eq "All"} { + +				delete_from_menu $fetch_m end +				delete_from_menu $fetch_m end + +				delete_from_menu $prune_m end +				delete_from_menu $prune_m end +			} +		} +	} +} +  proc populate_remotes_menu {} {  	global all_remotes @@ -229,6 +278,8 @@ proc populate_remotes_menu {} {  		add_fetch_entry $r  		add_push_entry $r  	} + +	update_all_remotes_menu_entry  }  proc add_single_remote {name location} { @@ -244,6 +295,8 @@ proc add_single_remote {name location} {  	add_fetch_entry $name  	add_push_entry $name + +	update_all_remotes_menu_entry  }  proc delete_from_menu {menu name} { @@ -264,8 +317,8 @@ proc remove_remote {name} {  		unset repo_config(remote.$name.push)  	} -	set i [lsearch -exact all_remotes $name] -	lreplace all_remotes $i $i +	set i [lsearch -exact $all_remotes $name] +	set all_remotes [lreplace $all_remotes $i $i]  	set remote_m .mbar.remote  	delete_from_menu $remote_m.fetch $name @@ -273,4 +326,6 @@ proc remove_remote {name} {  	delete_from_menu $remote_m.remove $name  	# Not all remotes are in the push menu  	catch { delete_from_menu $remote_m.push $name } + +	update_all_remotes_menu_entry  } diff --git a/git-gui/lib/remote_branch_delete.tcl b/git-gui/lib/remote_branch_delete.tcl index f872a3d89d..fcc06d03a1 100644 --- a/git-gui/lib/remote_branch_delete.tcl +++ b/git-gui/lib/remote_branch_delete.tcl @@ -251,7 +251,7 @@ method _write_url        {args} { set urltype url    }  method _write_check_head {args} { set checktype head }  method _write_head_list {args} { -	global current_branch +	global current_branch _last_merged_branch  	$head_m delete 0 end  	foreach abr $head_list { @@ -267,6 +267,13 @@ method _write_head_list {args} {  			set check_head $current_branch  		}  	} +	set lmb [lsearch -exact -sorted $head_list $_last_merged_branch] +	if {$lmb >= 0} { +		$w.heads.l conf -state normal +		$w.heads.l select set $lmb +		$w.heads.l yview $lmb +		$w.heads.l conf -state disabled +	}  }  method _write_urltype {args} { diff --git a/git-gui/lib/shortcut.tcl b/git-gui/lib/shortcut.tcl index 79c1888e11..78878ef89d 100644 --- a/git-gui/lib/shortcut.tcl +++ b/git-gui/lib/shortcut.tcl @@ -16,7 +16,7 @@ proc do_windows_shortcut {} {  					[info nameofexecutable] \  					[file normalize $::argv0] \  					] \ -					[file normalize [$_gitworktree]] +					[file normalize $_gitworktree]  			} err]} {  			error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]  		} @@ -57,7 +57,7 @@ proc do_cygwin_shortcut {} {  					$sh -c \  					"CHERE_INVOKING=1 source /etc/profile;[sq $me] &" \  					] \ -					[file normalize [$_gitworktree]] +					[file normalize $_gitworktree]  			} err]} {  			error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]  		} diff --git a/git-gui/lib/status_bar.tcl b/git-gui/lib/status_bar.tcl index 5fe3aad382..95cb44991f 100644 --- a/git-gui/lib/status_bar.tcl +++ b/git-gui/lib/status_bar.tcl @@ -39,6 +39,7 @@ method _oneline_pack {} {  }  constructor two_line {path} { +	global NS  	set w $path  	set w_l $w.l  	set w_c $w.c diff --git a/git-gui/lib/transport.tcl b/git-gui/lib/transport.tcl index 60e3a642c5..7fad9b7d91 100644 --- a/git-gui/lib/transport.tcl +++ b/git-gui/lib/transport.tcl @@ -20,6 +20,35 @@ proc prune_from {remote} {  	console::exec $w [list git remote prune $remote]  } +proc fetch_from_all {} { +	set w [console::new \ +		[mc "fetch all remotes"] \ +		[mc "Fetching new changes from all remotes"]] + +	set cmd [list git fetch --all] +	if {[is_config_true gui.pruneduringfetch]} { +		lappend cmd --prune +	} + +	console::exec $w $cmd +} + +proc prune_from_all {} { +	global all_remotes + +	set w [console::new \ +		[mc "remote prune all remotes"] \ +		[mc "Pruning tracking branches deleted from all remotes"]] + +	set cmd [list git remote prune] + +	foreach r $all_remotes { +		lappend cmd $r +	} + +	console::exec $w $cmd +} +  proc push_to {remote} {  	set w [console::new \  		[mc "push %s" $remote] \ @@ -123,6 +152,7 @@ proc do_push_anywhere {} {  		$w.source.l insert end $h  		if {$h eq $current_branch} {  			$w.source.l select set end +			$w.source.l yview end  		}  	}  	pack $w.source.l -side left -fill both -expand 1 @@ -135,7 +165,9 @@ proc do_push_anywhere {} {  			-value remote \  			-variable push_urltype  		if {$use_ttk} { -			ttk::combobox $w.dest.remote_m -textvariable push_remote \ +			ttk::combobox $w.dest.remote_m -state readonly \ +				-exportselection false \ +				-textvariable push_remote \  				-values $all_remotes  		} else {  			eval tk_optionMenu $w.dest.remote_m push_remote $all_remotes diff --git a/git-gui/lib/win32.tcl b/git-gui/lib/win32.tcl index d7f93d045d..db91ab84a5 100644 --- a/git-gui/lib/win32.tcl +++ b/git-gui/lib/win32.tcl @@ -18,9 +18,9 @@ proc win32_create_lnk {lnk_path lnk_exec lnk_dir} {  	eval [list exec wscript.exe \  		/E:jscript \  		/nologo \ -		[file join $oguilib win32_shortcut.js] \ +		[file nativename [file join $oguilib win32_shortcut.js]] \  		$lnk_path \ -		[file join $oguilib git-gui.ico] \ +		[file nativename [file join $oguilib git-gui.ico]] \  		$lnk_dir \  		$lnk_exec] $lnk_args  } | 
