Repository: jesseduffield/lazygit (language: go)

Issue:
No remote appears in the directories created with `worktree`
**Describe the bug**
When launching `lazygit` from a repo which has been created with the `worktree add` command, no `Remotes` appears. However, the `git branch -r` or `git remote` commands give the expected outputs.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to any git repository (which has at least one remote)
2. Create a clone of the repository with `git worktree add <path-to-new-folder>`
3. Go to this new folder
4. Launch lazygit and go to the `Remotes` block
5. No remote appears when one would expect the same remote list as in the original folder

When launched with the debug argument, no error is visible. And manually launching all the commands seems to give the expected behaviour :
```
Apr  7 11:42:55 |INFO| language: en
Apr  7 11:42:55 |INFO| RunCommand command="git --version"
Apr  7 11:42:55 |INFO| RunCommand command="git rev-parse --git-dir"
Apr  7 11:42:55 |INFO| RunCommand command="git config --get push.default"
Apr  7 11:42:55 |INFO| starting main loop
Apr  7 11:42:55 |INFO| Binary is not built with the buildBinary flag so we won't check for an update cont
ext="updates"
Apr  7 11:42:55 |INFO| RunCommand command="git fetch"
Apr  7 11:42:55 |INFO| refreshing all scopes in async mode
Apr  7 11:42:55 |INFO| RunCommand command="git stash list --pretty='%gs'"
Apr  7 11:42:55 |INFO| RunCommand command="git merge-base HEAD HEAD@{u}"
Apr  7 11:42:55 |INFO| RunCommand command="git tag --list"
Apr  7 11:42:55 |INFO| RunCommand command="git for-each-ref --sort=-committerdate --format=\"%(HEAD)|%(re
fname:short)|%(upstream:short)|%(upstream:track)\" refs/heads"
Apr  7 11:42:55 |INFO| RunCommand command="git status --untracked-files=all --porcelain -z "
Apr  7 11:42:55 |INFO| RunCommand command="git branch -r"
Apr  7 11:42:55 |INFO| RunCommand command="git for-each-ref --sort=-committerdate --format=\"%(HEAD)|%(re
fname:short)|%(upstream:short)|%(upstream:track)\" refs/heads"
Apr  7 11:42:55 |ERRO| fatal: no upstream configured for branch 'CloneRepo'
 command="git merge-base HEAD HEAD@{u}"
Apr  7 11:42:55 |INFO| RunCommand command="git symbolic-ref --short HEAD"
Apr  7 11:42:55 |INFO| RunCommand command="git merge-base HEAD master"
Apr  7 11:42:56 |INFO| refreshing the following scopes in async mode: branches,commits,remotes,tags
Apr  7 11:42:56 |INFO| RunCommand command="git tag --list"
Apr  7 11:42:56 |INFO| RunCommand command="git merge-base HEAD HEAD@{u}"
Apr  7 11:42:56 |INFO| RunCommand command="git branch -r"
Apr  7 11:42:56 |ERRO| fatal: no upstream configured for branch 'CloneRepo'
 command="git merge-base HEAD HEAD@{u}"
Apr  7 11:42:56 |INFO| RunCommand command="git for-each-ref --sort=-committerdate --format=\"%(HEAD)|%(re
fname:short)|%(upstream:short)|%(upstream:track)\" refs/heads"
Apr  7 11:42:56 |INFO| RunCommand command="git symbolic-ref --short HEAD"
Apr  7 11:42:56 |INFO| RunCommand command="git merge-base HEAD master"
```

**Expected behavior**
When launching lazygit from a git repository created with `git worktree` the list of remotes appears as in the original folders.

**Screenshots**
In repo created with `worktree` where there exists one remote repository `origin`:
```
$ git remote
origin
```
Nothing appears in the `Remotes` window
![image](https://user-images.githubusercontent.com/22468256/113848086-688fa680-9798-11eb-9dc3-1f8e7e2666e1.png)


**Desktop (please complete the following information):**
 - OS: Ubuntu 20.04
 - Lazygit Version `commit=, build date=2021-04-06, build source=debian, version=0.27, os=linux, arch=amd64`
 - The last commit id if you built project from sources: N/A, installed through apt-get

**Additional context**




Discussion / hints:
Just started to use lazygit; I too noticed this issue.
Lazygit doesn't seem to behave well with worktrees; #1280 asks for it as a feature.

Fix patch:
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index 6c6a3ac7c5e..64f0455b7af 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -63,7 +63,7 @@ func NewGitCommand(
 		return nil, err
 	}
 
-	repo, err := setupRepository(gogit.PlainOpen, cmn.Tr.GitconfigParseErr)
+	repo, err := setupRepository(gogit.PlainOpenWithOptions, gogit.PlainOpenOptions{DetectDotGit: false, EnableDotGitCommonDir: true}, cmn.Tr.GitconfigParseErr)
 	if err != nil {
 		return nil, err
 	}
@@ -207,7 +207,7 @@ func resolvePath(path string) (string, error) {
 	return filepath.EvalSymlinks(path)
 }
 
-func setupRepository(openGitRepository func(string) (*gogit.Repository, error), gitConfigParseErrorStr string) (*gogit.Repository, error) {
+func setupRepository(openGitRepository func(string, *gogit.PlainOpenOptions) (*gogit.Repository, error), options gogit.PlainOpenOptions, gitConfigParseErrorStr string) (*gogit.Repository, error) {
 	unresolvedPath := env.GetGitDirEnv()
 	if unresolvedPath == "" {
 		var err error
@@ -222,7 +222,7 @@ func setupRepository(openGitRepository func(string) (*gogit.Repository, error),
 		return nil, err
 	}
 
-	repository, err := openGitRepository(path)
+	repository, err := openGitRepository(path, &options)
 	if err != nil {
 		if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) {
 			return nil, errors.New(gitConfigParseErrorStr)
@@ -254,7 +254,7 @@ func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filenam
 	}
 	fileContent := string(fileBytes)
 	if !strings.HasPrefix(fileContent, "gitdir: ") {
-		return "", errors.New(".git is a file which suggests we are in a submodule but the file's contents do not contain a gitdir pointing to the actual .git directory")
+		return "", errors.New(".git is a file which suggests we are in a submodule or a worktree but the file's contents do not contain a gitdir pointing to the actual .git directory")
 	}
 	return strings.TrimSpace(strings.TrimPrefix(fileContent, "gitdir: ")), nil
 }


Test patch:
diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go
index a0faf3a7874..a36a5c6feab 100644
--- a/pkg/commands/git_test.go
+++ b/pkg/commands/git_test.go
@@ -116,18 +116,20 @@ func TestNavigateToRepoRootDirectory(t *testing.T) {
 func TestSetupRepository(t *testing.T) {
 	type scenario struct {
 		testName          string
-		openGitRepository func(string) (*gogit.Repository, error)
+		openGitRepository func(string, *gogit.PlainOpenOptions) (*gogit.Repository, error)
 		errorStr          string
+		options           gogit.PlainOpenOptions
 		test              func(*gogit.Repository, error)
 	}
 
 	scenarios := []scenario{
 		{
 			"A gitconfig parsing error occurred",
-			func(string) (*gogit.Repository, error) {
+			func(string, *gogit.PlainOpenOptions) (*gogit.Repository, error) {
 				return nil, fmt.Errorf(`unquoted '\' must be followed by new line`)
 			},
 			"error translated",
+			gogit.PlainOpenOptions{},
 			func(r *gogit.Repository, err error) {
 				assert.Error(t, err)
 				assert.EqualError(t, err, "error translated")
@@ -135,10 +137,11 @@ func TestSetupRepository(t *testing.T) {
 		},
 		{
 			"A gogit error occurred",
-			func(string) (*gogit.Repository, error) {
+			func(string, *gogit.PlainOpenOptions) (*gogit.Repository, error) {
 				return nil, fmt.Errorf("Error from inside gogit")
 			},
 			"",
+			gogit.PlainOpenOptions{},
 			func(r *gogit.Repository, err error) {
 				assert.Error(t, err)
 				assert.EqualError(t, err, "Error from inside gogit")
@@ -146,13 +149,14 @@ func TestSetupRepository(t *testing.T) {
 		},
 		{
 			"Setup done properly",
-			func(string) (*gogit.Repository, error) {
+			func(string, *gogit.PlainOpenOptions) (*gogit.Repository, error) {
 				assert.NoError(t, os.RemoveAll("/tmp/lazygit-test"))
 				r, err := gogit.PlainInit("/tmp/lazygit-test", false)
 				assert.NoError(t, err)
 				return r, nil
 			},
 			"",
+			gogit.PlainOpenOptions{},
 			func(r *gogit.Repository, err error) {
 				assert.NoError(t, err)
 				assert.NotNil(t, r)
@@ -163,7 +167,7 @@ func TestSetupRepository(t *testing.T) {
 	for _, s := range scenarios {
 		s := s
 		t.Run(s.testName, func(t *testing.T) {
-			s.test(setupRepository(s.openGitRepository, s.errorStr))
+			s.test(setupRepository(s.openGitRepository, s.options, s.errorStr))
 		})
 	}
 }