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}


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


proc appname {} { proc appname {} {
global _appname global _appname
@ -41,11 +43,56 @@ proc gitdir {args} {
return [eval [concat [list file join $_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 {} { proc reponame {} {
global _reponame global _reponame
return $_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 ## config
@ -234,6 +281,9 @@ if { [catch {set _gitdir $env(GIT_DIR)}]
error_popup "Cannot find the git directory:\n\n$err" error_popup "Cannot find the git directory:\n\n$err"
exit 1 exit 1
} }
if {![file isdirectory $_gitdir] && [is_Cygwin]} {
catch {set _gitdir [exec cygpath --unix $_gitdir]}
}
if {![file isdirectory $_gitdir]} { if {![file isdirectory $_gitdir]} {
catch {wm withdraw .} catch {wm withdraw .}
error_popup "Git directory not found:\n\n$_gitdir" error_popup "Git directory not found:\n\n$_gitdir"
@ -241,7 +291,7 @@ if {![file isdirectory $_gitdir]} {
} }
if {[lindex [file split $_gitdir] end] ne {.git}} { if {[lindex [file split $_gitdir] end] ne {.git}} {
catch {wm withdraw .} 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 exit 1
} }
if {[catch {cd [file dirname $_gitdir]} err]} { if {[catch {cd [file dirname $_gitdir]} err]} {
@ -1076,7 +1126,7 @@ A good commit message has the following format:
# On Cygwin [file executable] might lie so we need to ask # On Cygwin [file executable] might lie so we need to ask
# the shell if the hook is executable. Yes that's annoying. # 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 \ set pchook [list sh -c [concat \
"if test -x \"$pchook\";" \ "if test -x \"$pchook\";" \
"then exec \"$pchook\" 2>&1;" \ "then exec \"$pchook\" 2>&1;" \
@ -1215,7 +1265,7 @@ proc commit_committree {fd_wt curHEAD msg} {
# -- Run the post-commit hook. # -- Run the post-commit hook.
# #
set pchook [gitdir hooks post-commit] set pchook [gitdir hooks post-commit]
if {[is_Windows] && [file isfile $pchook]} { if {[is_Cygwin] && [file isfile $pchook]} {
set pchook [list sh -c [concat \ set pchook [list sh -c [concat \
"if test -x \"$pchook\";" \ "if test -x \"$pchook\";" \
"then exec \"$pchook\";" \ "then exec \"$pchook\";" \
@ -3020,22 +3070,6 @@ unset i
## ##
## util ## 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} { proc bind_button3 {w cmd} {
bind $w <Any-Button-3> $cmd bind $w <Any-Button-3> $cmd
if {[is_MacOSX]} { if {[is_MacOSX]} {
@ -3159,10 +3193,10 @@ proc console_init {w} {
} }


proc console_exec {w cmd after} { 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. :-( # 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 { }]"] set cmd [list sh --login -c "cd \"[pwd]\" && [join $cmd { }]"]
} }


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


proc do_gitk {revs} { 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 {}} { if {$revs ne {}} {
append cmd { } append cmd { }
append cmd $revs 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" error_popup "Failed to start gitk:\n\n$err"
} else { } else {
set ui_status_value $starting_gitk_msg set ui_status_value $starting_gitk_msg
@ -3894,6 +3936,29 @@ proc do_save_config {w} {
proc do_windows_shortcut {} { proc do_windows_shortcut {} {
global argv0 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 { if {[catch {
set desktop [exec cygpath \ set desktop [exec cygpath \
--windows \ --windows \
@ -3985,7 +4050,7 @@ proc do_macosx_app {} {


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


.mbar.repository add separator .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 \ .mbar.repository add command \
-label {Create Desktop Icon} \ -label {Create Desktop Icon} \
-command do_windows_shortcut \ -command do_windows_shortcut \
@ -4416,17 +4486,17 @@ if {![is_MacOSX]} {


set browser {} set browser {}
catch {set browser $repo_config(instaweb.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] set doc_path [file join $doc_path Documentation index.html]


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


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

Loading…
Cancel
Save