Browse Source

git-gui: Test for Cygwin differently than from Windows.

Running on Cygwin is different than if we were running through MinGW.

In the Cygwin case we have cygpath available to us, we need to perform
UNIX<->Windows path translation sometimes, and we need to perform odd
things like spawning our own login shells to perform network operations.
But in the MinGW case these don't occur.  Git knows native Windows file
paths, and login shells may not even exist.

Now git-gui will avoid running cygpath unless it knows its on Cygwin.
It also uses a different shortcut type when Cygwin is not present, and
it avoids invoking /bin/sh to execute hooks if Cygwin is not present.
This latter part probably needs more testing in the MinGW case.

This change also improves how we start gitk.  If the user is on any type
of Windows system its known that gitk won't start right if ~/.gitk exists.
So we delete it before starting if we are running on any type of Windows
operating system.  We always use the same wish executable which launched
git-gui to start gitk; this way on Windows we don't have to jump back to
/bin/sh just to go into the first wish found in the user's PATH.  This
should help on MinGW when we probably don't want to spawn a shell just
to start gitk.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
maint
Shawn O. Pearce 18 years ago
parent
commit
20ddfcaa7e
  1. 138
      git-gui.sh

138
git-gui.sh

@ -26,7 +26,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA} @@ -26,7 +26,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}

set _appname [lindex [file split $argv0] end]
set _gitdir {}
set _gitexec {}
set _reponame {}
set _iscygwin {}

proc appname {} {
global _appname
@ -41,11 +43,56 @@ proc gitdir {args} { @@ -41,11 +43,56 @@ proc gitdir {args} {
return [eval [concat [list file join $_gitdir] $args]]
}

proc gitexec {args} {
global _gitexec
if {$_gitexec eq {}} {
if {[catch {set _gitexec [exec git --exec-path]} err]} {
error "Git not installed?\n\n$err"
}
}
if {$args eq {}} {
return $_gitexec
}
return [eval [concat [list file join $_gitexec] $args]]
}

proc reponame {} {
global _reponame
return $_reponame
}

proc is_MacOSX {} {
global tcl_platform tk_library
if {[tk windowingsystem] eq {aqua}} {
return 1
}
return 0
}

proc is_Windows {} {
global tcl_platform
if {$tcl_platform(platform) eq {windows}} {
return 1
}
return 0
}

proc is_Cygwin {} {
global tcl_platform _iscygwin
if {$_iscygwin eq {}} {
if {$tcl_platform(platform) eq {windows}} {
if {[catch {set p [exec cygpath --windir]} err]} {
set _iscygwin 0
} else {
set _iscygwin 1
}
} else {
set _iscygwin 0
}
}
return $_iscygwin
}

######################################################################
##
## config
@ -234,6 +281,9 @@ if { [catch {set _gitdir $env(GIT_DIR)}] @@ -234,6 +281,9 @@ if { [catch {set _gitdir $env(GIT_DIR)}]
error_popup "Cannot find the git directory:\n\n$err"
exit 1
}
if {![file isdirectory $_gitdir] && [is_Cygwin]} {
catch {set _gitdir [exec cygpath --unix $_gitdir]}
}
if {![file isdirectory $_gitdir]} {
catch {wm withdraw .}
error_popup "Git directory not found:\n\n$_gitdir"
@ -241,7 +291,7 @@ if {![file isdirectory $_gitdir]} { @@ -241,7 +291,7 @@ if {![file isdirectory $_gitdir]} {
}
if {[lindex [file split $_gitdir] end] ne {.git}} {
catch {wm withdraw .}
error_popup "Cannot use funny .git directory:\n\n$gitdir"
error_popup "Cannot use funny .git directory:\n\n$_gitdir"
exit 1
}
if {[catch {cd [file dirname $_gitdir]} err]} {
@ -1076,7 +1126,7 @@ A good commit message has the following format: @@ -1076,7 +1126,7 @@ A good commit message has the following format:
# On Cygwin [file executable] might lie so we need to ask
# the shell if the hook is executable. Yes that's annoying.
#
if {[is_Windows] && [file isfile $pchook]} {
if {[is_Cygwin] && [file isfile $pchook]} {
set pchook [list sh -c [concat \
"if test -x \"$pchook\";" \
"then exec \"$pchook\" 2>&1;" \
@ -1215,7 +1265,7 @@ proc commit_committree {fd_wt curHEAD msg} { @@ -1215,7 +1265,7 @@ proc commit_committree {fd_wt curHEAD msg} {
# -- Run the post-commit hook.
#
set pchook [gitdir hooks post-commit]
if {[is_Windows] && [file isfile $pchook]} {
if {[is_Cygwin] && [file isfile $pchook]} {
set pchook [list sh -c [concat \
"if test -x \"$pchook\";" \
"then exec \"$pchook\";" \
@ -3020,22 +3070,6 @@ unset i @@ -3020,22 +3070,6 @@ unset i
##
## util

proc is_MacOSX {} {
global tcl_platform tk_library
if {[tk windowingsystem] eq {aqua}} {
return 1
}
return 0
}

proc is_Windows {} {
global tcl_platform
if {$tcl_platform(platform) eq {windows}} {
return 1
}
return 0
}

proc bind_button3 {w cmd} {
bind $w <Any-Button-3> $cmd
if {[is_MacOSX]} {
@ -3159,10 +3193,10 @@ proc console_init {w} { @@ -3159,10 +3193,10 @@ proc console_init {w} {
}

proc console_exec {w cmd after} {
# -- Windows tosses the enviroment when we exec our child.
# -- Cygwin's Tcl tosses the enviroment when we exec our child.
# But most users need that so we have to relogin. :-(
#
if {[is_Windows]} {
if {[is_Cygwin]} {
set cmd [list sh --login -c "cd \"[pwd]\" && [join $cmd { }]"]
}

@ -3284,19 +3318,27 @@ proc console_done {args} { @@ -3284,19 +3318,27 @@ proc console_done {args} {
set starting_gitk_msg {Starting gitk... please wait...}

proc do_gitk {revs} {
global ui_status_value starting_gitk_msg
global env ui_status_value starting_gitk_msg

# -- On Windows gitk is severly broken, and right now it seems like
# nobody cares about fixing it. The only known workaround is to
# always delete ~/.gitk before starting the program.
#
if {[is_Windows]} {
catch {file delete [file join $env(HOME) .gitk]}
}

set cmd gitk
# -- Always start gitk through whatever we were loaded with. This
# lets us bypass using shell process on Windows systems.
#
set cmd [info nameofexecutable]
lappend cmd [gitexec gitk]
if {$revs ne {}} {
append cmd { }
append cmd $revs
}
if {[is_Windows]} {
set cmd "sh -c \"exec $cmd\""
}
append cmd { &}

if {[catch {eval exec $cmd} err]} {
if {[catch {eval exec $cmd &} err]} {
error_popup "Failed to start gitk:\n\n$err"
} else {
set ui_status_value $starting_gitk_msg
@ -3894,6 +3936,29 @@ proc do_save_config {w} { @@ -3894,6 +3936,29 @@ proc do_save_config {w} {
proc do_windows_shortcut {} {
global argv0

set fn [tk_getSaveFile \
-parent . \
-title "[appname] ([reponame]): Create Desktop Icon" \
-initialfile "Git [reponame].bat"]
if {$fn != {}} {
if {[catch {
set fd [open $fn w]
puts $fd "@ECHO Entering [reponame]"
puts $fd "@ECHO Starting git-gui... please wait..."
puts $fd "@SET PATH=[file normalize [gitexec]];%PATH%"
puts $fd "@SET GIT_DIR=[file normalize [gitdir]]"
puts -nonewline $fd "@\"[info nameofexecutable]\""
puts $fd " \"[file normalize $argv0]\""
close $fd
} err]} {
error_popup "Cannot write script:\n\n$err"
}
}
}

proc do_cygwin_shortcut {} {
global argv0

if {[catch {
set desktop [exec cygpath \
--windows \
@ -3985,7 +4050,7 @@ proc do_macosx_app {} { @@ -3985,7 +4050,7 @@ proc do_macosx_app {} {

set fd [open $exe w]
set gd [file normalize [gitdir]]
set ep [file normalize [exec git --exec-path]]
set ep [file normalize [gitexec]]
regsub -all ' $gd "'\\''" gd
regsub -all ' $ep "'\\''" ep
puts $fd "#!/bin/sh"
@ -4211,7 +4276,12 @@ if {!$single_commit} { @@ -4211,7 +4276,12 @@ if {!$single_commit} {

.mbar.repository add separator

if {[is_Windows]} {
if {[is_Cygwin]} {
.mbar.repository add command \
-label {Create Desktop Icon} \
-command do_cygwin_shortcut \
-font font_ui
} elseif {[is_Windows]} {
.mbar.repository add command \
-label {Create Desktop Icon} \
-command do_windows_shortcut \
@ -4416,17 +4486,17 @@ if {![is_MacOSX]} { @@ -4416,17 +4486,17 @@ if {![is_MacOSX]} {

set browser {}
catch {set browser $repo_config(instaweb.browser)}
set doc_path [file dirname [exec git --exec-path]]
set doc_path [file dirname [gitexec]]
set doc_path [file join $doc_path Documentation index.html]

if {[is_Windows]} {
if {[is_Cygwin]} {
set doc_path [exec cygpath --windows $doc_path]
}

if {$browser eq {}} {
if {[is_MacOSX]} {
set browser open
} elseif {[is_Windows]} {
} elseif {[is_Cygwin]} {
set program_files [file dirname [exec cygpath --windir]]
set program_files [file join $program_files {Program Files}]
set firefox [file join $program_files {Mozilla Firefox} firefox.exe]
@ -4988,7 +5058,7 @@ focus -force $ui_comm @@ -4988,7 +5058,7 @@ focus -force $ui_comm
# does *not* pass its env array onto any processes it spawns.
# This means that git processes get none of our environment.
#
if {[is_Windows]} {
if {[is_Cygwin]} {
set ignored_env 0
set suggest_user {}
set msg "Possible environment issues exist.

Loading…
Cancel
Save