1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-01-20 05:19:24 +02:00

Fix seg-fault when opening submodule in nested folder (#2903)

This commit is contained in:
Jesse Duffield 2023-08-08 00:03:28 +10:00 committed by GitHub
commit 4c89f9fba5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 9 deletions

View File

@ -157,6 +157,10 @@ func linkedWorktreeGitDirPath(fs afero.Fs, worktreePath string) (string, error)
} }
gitDir := strings.TrimPrefix(gitDirLine[0], "gitdir: ") gitDir := strings.TrimPrefix(gitDirLine[0], "gitdir: ")
// For windows support
gitDir = filepath.ToSlash(gitDir)
return gitDir, nil return gitDir, nil
} }
@ -194,19 +198,32 @@ func getCurrentRepoGitDirPath(
return "", "", errors.Errorf("could not find git dir for %s: %v", currentPath, err) return "", "", errors.Errorf("could not find git dir for %s: %v", currentPath, err)
} }
// confirm whether the next directory up is the worktrees/submodules directory _, err = fs.Stat(worktreeGitPath)
parent := path.Dir(worktreeGitPath) if err != nil {
if path.Base(parent) != "worktrees" && path.Base(parent) != "modules" { if os.IsNotExist(err) {
return "", "", errors.Errorf("could not find git dir for %s", currentPath) // hardcoding error to get around windows-specific error message
return "", "", errors.Errorf("could not find git dir for %s. %s does not exist", currentPath, worktreeGitPath)
}
return "", "", errors.Errorf("could not find git dir for %s: %v", currentPath, err)
} }
// if it's a submodule, we treat it as its own repo // confirm whether the next directory up is the worktrees directory
if path.Base(parent) == "modules" { parent := path.Dir(worktreeGitPath)
if path.Base(parent) == "worktrees" {
gitDirPath := path.Dir(parent)
return gitDirPath, path.Dir(gitDirPath), nil
}
// Unlike worktrees, submodules can be nested arbitrarily deep, so we check
// if the `modules` directory is anywhere up the chain.
if strings.Contains(worktreeGitPath, "/modules/") {
// For submodules, we just return the path directly
return worktreeGitPath, currentPath, nil return worktreeGitPath, currentPath, nil
} }
gitDirPath := path.Dir(parent) // If this error causes issues, we could relax the constraint and just always
return gitDirPath, path.Dir(gitDirPath), nil // return the path
return "", "", errors.Errorf("could not find git dir for %s: path is not under `worktrees` or `modules` directories", currentPath)
} }
// takes a path containing a symlink and returns the true path // takes a path containing a symlink and returns the true path

View File

@ -73,7 +73,7 @@ func TestGetRepoPathsAux(t *testing.T) {
}, },
Path: "/path/to/repo/worktree2", Path: "/path/to/repo/worktree2",
Expected: nil, Expected: nil,
Err: errors.New("failed to get repo git dir path: could not find git dir for /path/to/repo/worktree2"), Err: errors.New("failed to get repo git dir path: could not find git dir for /path/to/repo/worktree2. /nonexistant does not exist"),
}, },
{ {
Name: "submodule", Name: "submodule",
@ -92,6 +92,33 @@ func TestGetRepoPathsAux(t *testing.T) {
}, },
Err: nil, Err: nil,
}, },
{
Name: "submodule in nested directory",
BeforeFunc: func(fs afero.Fs) {
_ = fs.MkdirAll("/path/to/repo/.git/modules/my/submodule1", 0o755)
_ = afero.WriteFile(fs, "/path/to/repo/my/submodule1/.git", []byte("gitdir: /path/to/repo/.git/modules/my/submodule1"), 0o644)
},
Path: "/path/to/repo/my/submodule1",
Expected: &RepoPaths{
currentPath: "/path/to/repo/my/submodule1",
worktreePath: "/path/to/repo/my/submodule1",
worktreeGitDirPath: "/path/to/repo/.git/modules/my/submodule1",
repoPath: "/path/to/repo/my/submodule1",
repoGitDirPath: "/path/to/repo/.git/modules/my/submodule1",
repoName: "submodule1",
},
Err: nil,
},
{
Name: "submodule git dir not under .git/modules",
BeforeFunc: func(fs afero.Fs) {
_ = fs.MkdirAll("/random/submodule1", 0o755)
_ = afero.WriteFile(fs, "/path/to/repo/my/submodule1/.git", []byte("gitdir: /random/submodule1"), 0o644)
},
Path: "/path/to/repo/my/submodule1",
Expected: nil,
Err: errors.New("failed to get repo git dir path: could not find git dir for /path/to/repo/my/submodule1: path is not under `worktrees` or `modules` directories"),
},
} }
for _, s := range scenarios { for _, s := range scenarios {