Repository: JanDeDobbeleer/oh-my-posh
Pull request #1203 (2021-11-10 15:54:26)

fix(git): read real worktree folder from gitdir
### Prerequisites

- [x] I have read and understood the `CONTRIBUTING` guide
- [ ] The commit message follows the [conventional commits][cc] guidelines
- [x] Tests for the changes have been added (for bug fixes/features)
- [ ] Docs have been added / updated (for bug fixes/features)

### Description

[Description of the change]

<!---

Tips:

If you're not comfortable with working with Git, we're working a guide (https://ohmyposh.dev/docs/contributing_git) to help you out.
Oh My Posh advises GitKraken (https://www.gitkraken.com/invite/nQmDPR9D) as your preferred cross platform Git GUI power tool.

-->

[cc]: https://www.conventionalcommits.org/en/v1.0.0/#summary


JanDeDobbeleer: Ah good, was on my list for this evening :-)
lnu: Still have to check how it fits with the submodule thing
lnu: submodules working:
![image](https://user-images.githubusercontent.com/1829553/141302474-de5ac9c5-948e-4e76-a769-328a9ae2d375.png)

lnu: I have no issues with windows path in wsl(/mnt/d/xxx) but I'll check the issue. https://github.com/JanDeDobbeleer/oh-my-posh/discussions/1195#discussioncomment-1624759

Patch:
diff --git a/src/segment_git.go b/src/segment_git.go
index c02ffa59..4b93eaf7 100644
--- a/src/segment_git.go
+++ b/src/segment_git.go
@@ -78,8 +78,9 @@ 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
+	gitWorkingFolder  string // .git working folder, can be different of root if using worktree
+	gitRootFolder     string // .git root folder
+	gitWorktreeFolder string // .git real worktree path
 }
 
 const (
@@ -152,8 +153,7 @@ func (g *git) enabled() bool {
 	}
 	// handle worktree
 	g.gitRootFolder = gitdir.path
-	dirPointer := g.env.getFileContent(gitdir.path)
-	dirPointer = strings.Trim(dirPointer, " \r\n")
+	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"]
@@ -162,6 +162,7 @@ func (g *git) enabled() bool {
 		// :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.IsWorkTree = true
 		return true
 	}
@@ -292,7 +293,7 @@ func (g *git) getGitCommand() string {
 }
 
 func (g *git) getGitCommandOutput(args ...string) string {
-	args = append([]string{"--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
+	args = append([]string{"-C", g.gitWorktreeFolder, "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
 	val, _ := g.env.runCommand(g.getGitCommand(), args...)
 	return val
 }


Test patch:
diff --git a/src/segment_git_test.go b/src/segment_git_test.go
index 2b48792d..4fde6b30 100644
--- a/src/segment_git_test.go
+++ b/src/segment_git_test.go
@@ -46,21 +46,23 @@ func TestEnabledInWorkingTree(t *testing.T) {
 	env.On("getRuntimeGOOS", nil).Return("")
 	env.On("isWsl", nil).Return(false)
 	fileInfo := &fileInfo{
-		path:         "/dir/hello",
-		parentFolder: "/dir",
+		path:         "/dev/folder_worktree/.git",
+		parentFolder: "/dev/folder_worktree",
 		isDir:        false,
 	}
 	env.On("hasParentFilePath", ".git").Return(fileInfo, nil)
-	env.On("getFileContent", "/dir/hello").Return("gitdir: /dir/hello/burp/burp")
+	env.On("getFileContent", "/dev/folder_worktree/.git").Return("gitdir: /dev/real_folder/.git/worktrees/folder_worktree")
+	env.On("getFileContent", "/dev/real_folder/.git/worktrees/folder_worktree/gitdir").Return("/dev/folder_worktree.git\n")
 	g := &git{
 		env: env,
 	}
 	assert.True(t, g.enabled())
-	assert.Equal(t, "/dir/hello/burp/burp", g.gitWorkingFolder)
+	assert.Equal(t, "/dev/real_folder/.git/worktrees/folder_worktree", g.gitWorkingFolder)
+	assert.Equal(t, "/dev/folder_worktree", g.gitWorktreeFolder)
 }
 
 func TestGetGitOutputForCommand(t *testing.T) {
-	args := []string{"--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}
+	args := []string{"-C", "", "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}
 	commandArgs := []string{"symbolic-ref", "--short", "HEAD"}
 	want := "je suis le output"
 	env := new(MockedEnvironment)
@@ -137,7 +139,7 @@ func setupHEADContextEnv(context *detachedContext) *git {
 }
 
 func (m *MockedEnvironment) mockGitCommand(returnValue string, args ...string) {
-	args = append([]string{"--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
+	args = append([]string{"-C", "", "--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false"}, args...)
 	m.On("runCommand", "git", args).Return(returnValue, nil)
 }
 
@@ -550,7 +552,8 @@ func TestGitUpstream(t *testing.T) {
 	for _, tc := range cases {
 		env := &MockedEnvironment{}
 		env.On("isWsl", nil).Return(false)
-		env.On("runCommand", "git", []string{"--no-optional-locks", "-c", "core.quotepath=false", "-c", "color.status=false", "remote", "get-url", "origin"}).Return(tc.Upstream, nil)
+		env.On("runCommand", "git", []string{"-C", "", "--no-optional-locks", "-c", "core.quotepath=false",
+			"-c", "color.status=false", "remote", "get-url", "origin"}).Return(tc.Upstream, nil)
 		env.On("getRuntimeGOOS", nil).Return("unix")
 		props := &properties{
 			values: map[Property]interface{}{