mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-02-21 02:55:37 -08:00
fix(git): use the right git executable for WSL
git executable detection path conversion when needed
This commit is contained in:
parent
52d7badbac
commit
77993158e2
|
@ -100,12 +100,16 @@ type environmentInfo interface {
|
|||
doGet(url string, timeout int, requestModifiers ...HTTPRequestModifier) ([]byte, error)
|
||||
hasParentFilePath(path string) (fileInfo *fileInfo, err error)
|
||||
isWsl() bool
|
||||
isWsl2() bool
|
||||
stackCount() int
|
||||
getTerminalWidth() (int, error)
|
||||
getCachePath() string
|
||||
cache() cache
|
||||
close()
|
||||
logs() string
|
||||
inWSLSharedDrive() bool
|
||||
convertToLinuxPath(path string) string
|
||||
convertToWindowsPath(path string) string
|
||||
}
|
||||
|
||||
type commandCache struct {
|
||||
|
|
|
@ -5,6 +5,7 @@ package main
|
|||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/shirou/gopsutil/v3/host"
|
||||
|
@ -33,6 +34,15 @@ func (env *environment) isWsl() bool {
|
|||
return env.getenv("WSL_DISTRO_NAME") != ""
|
||||
}
|
||||
|
||||
func (env *environment) isWsl2() bool {
|
||||
defer env.trace(time.Now(), "isWsl2")
|
||||
if !env.isWsl() {
|
||||
return false
|
||||
}
|
||||
uname := env.getFileContent("/proc/sys/kernel/osrelease")
|
||||
return strings.Contains(uname, "WSL2")
|
||||
}
|
||||
|
||||
func (env *environment) getTerminalWidth() (int, error) {
|
||||
defer env.trace(time.Now(), "getTerminalWidth")
|
||||
width, err := terminal.Width()
|
||||
|
@ -63,3 +73,23 @@ func (env *environment) getCachePath() string {
|
|||
func (env *environment) getWindowsRegistryKeyValue(path string) (*windowsRegistryValue, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
func (env *environment) inWSLSharedDrive() bool {
|
||||
return env.isWsl() && strings.HasPrefix(env.getcwd(), "/mnt/")
|
||||
}
|
||||
|
||||
func (env *environment) convertToWindowsPath(path string) string {
|
||||
windowsPath, err := env.runCommand("wslpath", "-w", path)
|
||||
if err == nil {
|
||||
return windowsPath
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func (env *environment) convertToLinuxPath(path string) string {
|
||||
linuxPath, err := env.runCommand("wslpath", "-u", path)
|
||||
if err == nil {
|
||||
return linuxPath
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
|
|
@ -75,6 +75,11 @@ func (env *environment) isWsl() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (env *environment) isWsl2() bool {
|
||||
defer env.trace(time.Now(), "isWsl2")
|
||||
return false
|
||||
}
|
||||
|
||||
func (env *environment) getTerminalWidth() (int, error) {
|
||||
defer env.trace(time.Now(), "getTerminalWidth")
|
||||
handle, err := syscall.Open("CONOUT$", syscall.O_RDWR, 0)
|
||||
|
@ -243,3 +248,15 @@ func (env *environment) getWindowsRegistryKeyValue(path string) (*windowsRegistr
|
|||
return nil, errors.New(errorLogMsg)
|
||||
}
|
||||
}
|
||||
|
||||
func (env *environment) inWSLSharedDrive() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (env *environment) convertToWindowsPath(path string) string {
|
||||
return path
|
||||
}
|
||||
|
||||
func (env *environment) convertToLinuxPath(path string) string {
|
||||
return path
|
||||
}
|
||||
|
|
|
@ -45,11 +45,13 @@ type git struct {
|
|||
WorktreeCount int
|
||||
IsWorkTree bool
|
||||
|
||||
gitWorkingFolder string // .git working folder, can be different of root if using worktree
|
||||
gitRootFolder string // .git root folder
|
||||
gitWorktreeFolder string // .git real worktree path
|
||||
gitWorkingFolder string // .git working folder
|
||||
gitRootFolder string // .git root folder
|
||||
gitRealFolder string // .git real folder(can be different from current path when in worktrees)
|
||||
|
||||
gitCommand string
|
||||
|
||||
IsWslSharedPath bool
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -102,6 +104,10 @@ const (
|
|||
)
|
||||
|
||||
func (g *git) enabled() bool {
|
||||
// when in wsl/wsl2 and in a windows shared folder
|
||||
// we must use git.exe and convert paths accordingly
|
||||
// for worktrees, stashes, and path to work
|
||||
g.IsWslSharedPath = g.env.inWSLSharedDrive()
|
||||
if !g.env.hasCommand(g.getGitCommand()) {
|
||||
return false
|
||||
}
|
||||
|
@ -116,7 +122,8 @@ func (g *git) enabled() bool {
|
|||
if gitdir.isDir {
|
||||
g.gitWorkingFolder = gitdir.path
|
||||
g.gitRootFolder = gitdir.path
|
||||
g.gitWorktreeFolder = strings.TrimSuffix(gitdir.path, ".git")
|
||||
// convert the worktree file path to a windows one when in wsl 2 shared folder
|
||||
g.gitRealFolder = strings.TrimSuffix(g.convertToWindowsPath(gitdir.path), ".git")
|
||||
return true
|
||||
}
|
||||
// handle worktree
|
||||
|
@ -124,13 +131,15 @@ func (g *git) enabled() bool {
|
|||
dirPointer := strings.Trim(g.env.getFileContent(gitdir.path), " \r\n")
|
||||
matches := findNamedRegexMatch(`^gitdir: (?P<dir>.*)$`, dirPointer)
|
||||
if matches != nil && matches["dir"] != "" {
|
||||
g.gitWorkingFolder = matches["dir"]
|
||||
// if we open a worktree file in a shared wsl2 folder, we have to convert it back
|
||||
// to the mounted path
|
||||
g.gitWorkingFolder = g.convertToLinuxPath(matches["dir"])
|
||||
// in worktrees, the path looks like this: gitdir: path/.git/worktrees/branch
|
||||
// strips the last .git/worktrees part
|
||||
// :ind+5 = index + /.git
|
||||
ind := strings.LastIndex(g.gitWorkingFolder, "/.git/worktrees")
|
||||
g.gitRootFolder = g.gitWorkingFolder[:ind+5]
|
||||
g.gitWorktreeFolder = strings.TrimSuffix(g.env.getFileContent(g.gitWorkingFolder+"/gitdir"), ".git\n")
|
||||
g.gitRealFolder = strings.TrimSuffix(g.env.getFileContent(g.gitWorkingFolder+"/gitdir"), ".git\n")
|
||||
g.IsWorkTree = true
|
||||
return true
|
||||
}
|
||||
|
@ -278,25 +287,15 @@ func (g *git) getGitCommand() string {
|
|||
if len(g.gitCommand) > 0 {
|
||||
return g.gitCommand
|
||||
}
|
||||
inWSL2SharedDrive := func(env environmentInfo) bool {
|
||||
if !env.isWsl() {
|
||||
return false
|
||||
}
|
||||
if !strings.HasPrefix(env.getcwd(), "/mnt/") {
|
||||
return false
|
||||
}
|
||||
uname, _ := g.env.runCommand("uname", "-r")
|
||||
return strings.Contains(uname, "WSL2")
|
||||
}
|
||||
g.gitCommand = "git"
|
||||
if g.env.getRuntimeGOOS() == windowsPlatform || inWSL2SharedDrive(g.env) {
|
||||
if g.env.getRuntimeGOOS() == windowsPlatform || g.IsWslSharedPath {
|
||||
g.gitCommand = "git.exe"
|
||||
}
|
||||
return g.gitCommand
|
||||
}
|
||||
|
||||
func (g *git) getGitCommandOutput(args ...string) string {
|
||||
args = append([]string{"-C", g.gitWorktreeFolder, "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
|
||||
args = append([]string{"-C", g.gitRealFolder, "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
|
||||
val, _ := g.env.runCommand(g.getGitCommand(), args...)
|
||||
return val
|
||||
}
|
||||
|
@ -490,3 +489,17 @@ func (g *git) getOriginURL(upstream string) string {
|
|||
}
|
||||
return keyVal
|
||||
}
|
||||
|
||||
func (g *git) convertToWindowsPath(path string) string {
|
||||
if !g.IsWslSharedPath {
|
||||
return path
|
||||
}
|
||||
return g.env.convertToWindowsPath(path)
|
||||
}
|
||||
|
||||
func (g *git) convertToLinuxPath(path string) string {
|
||||
if !g.IsWslSharedPath {
|
||||
return path
|
||||
}
|
||||
return g.env.convertToLinuxPath(path)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ const (
|
|||
|
||||
func TestEnabledGitNotFound(t *testing.T) {
|
||||
env := new(MockedEnvironment)
|
||||
env.On("inWSLSharedDrive", nil).Return(false)
|
||||
env.On("hasCommand", "git").Return(false)
|
||||
env.On("getRuntimeGOOS", nil).Return("")
|
||||
env.On("isWsl", nil).Return(false)
|
||||
|
@ -28,6 +29,7 @@ func TestEnabledGitNotFound(t *testing.T) {
|
|||
|
||||
func TestEnabledInWorkingDirectory(t *testing.T) {
|
||||
env := new(MockedEnvironment)
|
||||
env.On("inWSLSharedDrive", nil).Return(false)
|
||||
env.On("hasCommand", "git").Return(true)
|
||||
env.On("getRuntimeGOOS", nil).Return("")
|
||||
env.On("isWsl", nil).Return(false)
|
||||
|
@ -48,6 +50,7 @@ func TestEnabledInWorkingDirectory(t *testing.T) {
|
|||
|
||||
func TestEnabledInWorkingTree(t *testing.T) {
|
||||
env := new(MockedEnvironment)
|
||||
env.On("inWSLSharedDrive", nil).Return(false)
|
||||
env.On("hasCommand", "git").Return(true)
|
||||
env.On("getRuntimeGOOS", nil).Return("")
|
||||
env.On("isWsl", nil).Return(false)
|
||||
|
@ -66,7 +69,7 @@ func TestEnabledInWorkingTree(t *testing.T) {
|
|||
}
|
||||
assert.True(t, g.enabled())
|
||||
assert.Equal(t, "/dev/real_folder/.git/worktrees/folder_worktree", g.gitWorkingFolder)
|
||||
assert.Equal(t, "/dev/folder_worktree", g.gitWorktreeFolder)
|
||||
assert.Equal(t, "/dev/folder_worktree", g.gitRealFolder)
|
||||
}
|
||||
|
||||
func TestGetGitOutputForCommand(t *testing.T) {
|
||||
|
@ -195,6 +198,7 @@ func TestSetGitHEADContextClean(t *testing.T) {
|
|||
}
|
||||
for _, tc := range cases {
|
||||
env := new(MockedEnvironment)
|
||||
env.On("inWSLSharedDrive", nil).Return(false)
|
||||
env.On("getRuntimeGOOS", nil).Return("unix")
|
||||
env.On("isWsl", nil).Return(false)
|
||||
env.mockGitCommand("", "describe", "--tags", "--exact-match")
|
||||
|
@ -537,17 +541,18 @@ func TestShouldIgnoreRootRepository(t *testing.T) {
|
|||
|
||||
func TestGetGitCommand(t *testing.T) {
|
||||
cases := []struct {
|
||||
Case string
|
||||
Expected string
|
||||
IsWSL bool
|
||||
IsWSL1 bool
|
||||
GOOS string
|
||||
CWD string
|
||||
Case string
|
||||
Expected string
|
||||
IsWSL bool
|
||||
IsWSL1 bool
|
||||
GOOS string
|
||||
CWD string
|
||||
IsWslSharedPath bool
|
||||
}{
|
||||
{Case: "On Windows", Expected: "git.exe", GOOS: windowsPlatform},
|
||||
{Case: "Non Windows", Expected: "git"},
|
||||
{Case: "Iside WSL2, non shared", IsWSL: true, Expected: "git"},
|
||||
{Case: "Iside WSL2, shared", Expected: "git.exe", IsWSL: true, CWD: "/mnt/bill"},
|
||||
{Case: "Iside WSL2, shared", Expected: "git.exe", IsWSL: true, IsWslSharedPath: true, CWD: "/mnt/bill"},
|
||||
{Case: "Iside WSL1, shared", Expected: "git", IsWSL: true, IsWSL1: true, CWD: "/mnt/bill"},
|
||||
}
|
||||
|
||||
|
@ -566,6 +571,12 @@ func TestGetGitCommand(t *testing.T) {
|
|||
env: env,
|
||||
},
|
||||
}
|
||||
if tc.IsWslSharedPath {
|
||||
env.On("inWSLSharedDrive", nil).Return(true)
|
||||
g.IsWslSharedPath = tc.IsWslSharedPath
|
||||
} else {
|
||||
env.On("inWSLSharedDrive", nil).Return(false)
|
||||
}
|
||||
assert.Equal(t, tc.Expected, g.getGitCommand(), tc.Case)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,6 +154,11 @@ func (env *MockedEnvironment) isWsl() bool {
|
|||
return args.Bool(0)
|
||||
}
|
||||
|
||||
func (env *MockedEnvironment) isWsl2() bool {
|
||||
args := env.Called(nil)
|
||||
return args.Bool(0)
|
||||
}
|
||||
|
||||
func (env *MockedEnvironment) getTerminalWidth() (int, error) {
|
||||
args := env.Called(nil)
|
||||
return args.Int(0), args.Error(1)
|
||||
|
@ -178,6 +183,21 @@ func (env *MockedEnvironment) logs() string {
|
|||
return args.String(0)
|
||||
}
|
||||
|
||||
func (env *MockedEnvironment) inWSLSharedDrive() bool {
|
||||
args := env.Called(nil)
|
||||
return args.Bool(0)
|
||||
}
|
||||
|
||||
func (env *MockedEnvironment) convertToWindowsPath(path string) string {
|
||||
args := env.Called(nil)
|
||||
return args.String(0)
|
||||
}
|
||||
|
||||
func (env *MockedEnvironment) convertToLinuxPath(path string) string {
|
||||
args := env.Called(nil)
|
||||
return args.String(0)
|
||||
}
|
||||
|
||||
const (
|
||||
homeBill = "/home/bill"
|
||||
homeJan = "/usr/home/jan"
|
||||
|
|
Loading…
Reference in a new issue