mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-12 04:45:47 +02:00
Add test for opening lazygit in the worktree of a bare repo
This commit is contained in:
parent
e874f94cf8
commit
2b24c15938
5 changed files with 109 additions and 28 deletions
|
@ -1,6 +1,7 @@
|
||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -66,13 +67,16 @@ func NewGitCommand(
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := setupRepository(gogit.PlainOpenWithOptions, gogit.PlainOpenOptions{DetectDotGit: false, EnableDotGitCommonDir: true}, cmn.Tr.GitconfigParseErr)
|
dotGitDir, err := findDotGitDir(os.Stat, os.ReadFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dotGitDir, err := findDotGitDir(os.Stat, os.ReadFile)
|
repository, err := gogit.PlainOpenWithOptions(dotGitDir, &gogit.PlainOpenOptions{DetectDotGit: false, EnableDotGitCommonDir: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) {
|
||||||
|
return nil, errors.New(cmn.Tr.GitconfigParseErr)
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +86,7 @@ func NewGitCommand(
|
||||||
osCommand,
|
osCommand,
|
||||||
gitConfig,
|
gitConfig,
|
||||||
dotGitDir,
|
dotGitDir,
|
||||||
repo,
|
repository,
|
||||||
syncMutex,
|
syncMutex,
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
@ -218,8 +222,8 @@ func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolvePath takes a path containing a symlink and returns the true path
|
// takes a path containing a symlink and returns the true path
|
||||||
func resolvePath(path string) (string, error) {
|
func resolveSymlink(path string) (string, error) {
|
||||||
l, err := os.Lstat(path)
|
l, err := os.Lstat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -232,27 +236,17 @@ func resolvePath(path string) (string, error) {
|
||||||
return filepath.EvalSymlinks(path)
|
return filepath.EvalSymlinks(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupRepository(openGitRepository func(string, *gogit.PlainOpenOptions) (*gogit.Repository, error), options gogit.PlainOpenOptions, gitConfigParseErrorStr string) (*gogit.Repository, error) {
|
func setupRepository(
|
||||||
unresolvedPath := env.GetGitDirEnv()
|
openGitRepository func(string, *gogit.PlainOpenOptions) (*gogit.Repository, error),
|
||||||
if unresolvedPath == "" {
|
options gogit.PlainOpenOptions,
|
||||||
var err error
|
gitConfigParseErrorStr string,
|
||||||
unresolvedPath, err = os.Getwd()
|
path string,
|
||||||
if err != nil {
|
) (*gogit.Repository, error) {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
path, err := resolvePath(unresolvedPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
repository, err := openGitRepository(path, &options)
|
repository, err := openGitRepository(path, &options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) {
|
if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) {
|
||||||
return nil, errors.New(gitConfigParseErrorStr)
|
return nil, errors.New(gitConfigParseErrorStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,26 +254,38 @@ func setupRepository(openGitRepository func(string, *gogit.PlainOpenOptions) (*g
|
||||||
}
|
}
|
||||||
|
|
||||||
func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filename string) ([]byte, error)) (string, error) {
|
func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filename string) ([]byte, error)) (string, error) {
|
||||||
if env.GetGitDirEnv() != "" {
|
unresolvedPath := env.GetGitDirEnv()
|
||||||
return env.GetGitDirEnv(), nil
|
if unresolvedPath == "" {
|
||||||
|
var err error
|
||||||
|
unresolvedPath, err = os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
unresolvedPath = filepath.Join(unresolvedPath, ".git")
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := stat(".git")
|
path, err := resolveSymlink(unresolvedPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.IsDir() {
|
if f.IsDir() {
|
||||||
return ".git", nil
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
fileBytes, err := readFile(".git")
|
fileBytes, err := readFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
fileContent := string(fileBytes)
|
fileContent := string(fileBytes)
|
||||||
if !strings.HasPrefix(fileContent, "gitdir: ") {
|
if !strings.HasPrefix(fileContent, "gitdir: ") {
|
||||||
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 "", errors.New(fmt.Sprintf("%s 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", path))
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(strings.TrimPrefix(fileContent, "gitdir: ")), nil
|
return strings.TrimSpace(strings.TrimPrefix(fileContent, "gitdir: ")), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,11 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
|
||||||
current = nil
|
current = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if splitLine == "bare" {
|
||||||
|
current = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(splitLine, "worktree ") {
|
if strings.HasPrefix(splitLine, "worktree ") {
|
||||||
path := strings.SplitN(splitLine, " ", 2)[1]
|
path := strings.SplitN(splitLine, " ", 2)[1]
|
||||||
isMain := path == currentRepoPath
|
isMain := path == currentRepoPath
|
||||||
|
|
|
@ -85,7 +85,7 @@ func (self *Shell) CreateFile(path string, content string) *Shell {
|
||||||
|
|
||||||
func (self *Shell) DeleteFile(path string) *Shell {
|
func (self *Shell) DeleteFile(path string) *Shell {
|
||||||
fullPath := filepath.Join(self.dir, path)
|
fullPath := filepath.Join(self.dir, path)
|
||||||
err := os.Remove(fullPath)
|
err := os.RemoveAll(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
self.fail(fmt.Sprintf("error deleting file: %s\n%s", fullPath, err))
|
self.fail(fmt.Sprintf("error deleting file: %s\n%s", fullPath, err))
|
||||||
}
|
}
|
||||||
|
@ -328,3 +328,11 @@ func (self *Shell) CopyFile(source string, destination string) *Shell {
|
||||||
|
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: this only takes effect before running the test;
|
||||||
|
// the test will still run in the original directory
|
||||||
|
func (self *Shell) Chdir(path string) *Shell {
|
||||||
|
self.dir = filepath.Join(self.dir, path)
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
|
@ -223,6 +223,7 @@ var tests = []*components.IntegrationTest{
|
||||||
worktree.AddFromBranch,
|
worktree.AddFromBranch,
|
||||||
worktree.AddFromBranchDetached,
|
worktree.AddFromBranchDetached,
|
||||||
worktree.AddFromCommit,
|
worktree.AddFromCommit,
|
||||||
|
worktree.BareRepo,
|
||||||
worktree.Bisect,
|
worktree.Bisect,
|
||||||
worktree.Crud,
|
worktree.Crud,
|
||||||
worktree.CustomCommand,
|
worktree.CustomCommand,
|
||||||
|
|
61
pkg/integration/tests/worktree/bare_repo.go
Normal file
61
pkg/integration/tests/worktree/bare_repo.go
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package worktree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var BareRepo = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Open lazygit in the worktree of a bare repo",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
// we're going to have a directory structure like this:
|
||||||
|
// project
|
||||||
|
// - .bare
|
||||||
|
// - repo (a worktree)
|
||||||
|
// - worktree2 (another worktree)
|
||||||
|
//
|
||||||
|
// The first repo is called 'repo' because that's the
|
||||||
|
// directory that all lazygit tests start in
|
||||||
|
|
||||||
|
shell.NewBranch("mybranch")
|
||||||
|
shell.CreateFileAndAdd("blah", "blah")
|
||||||
|
shell.Commit("initial commit")
|
||||||
|
|
||||||
|
shell.RunCommand([]string{"git", "clone", "--bare", ".", "../.bare"})
|
||||||
|
|
||||||
|
shell.DeleteFile(".git")
|
||||||
|
|
||||||
|
shell.Chdir("..")
|
||||||
|
|
||||||
|
// This is the dir we were just in (and the dir that lazygit starts in when the test runs)
|
||||||
|
// We're going to replace it with a worktree
|
||||||
|
shell.DeleteFile("repo")
|
||||||
|
|
||||||
|
shell.RunCommand([]string{"git", "--git-dir", ".bare", "worktree", "add", "-b", "repo", "repo", "mybranch"})
|
||||||
|
shell.RunCommand([]string{"git", "--git-dir", ".bare", "worktree", "add", "-b", "worktree2", "worktree2", "mybranch"})
|
||||||
|
},
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
t.Views().Branches().
|
||||||
|
Lines(
|
||||||
|
Contains("repo"),
|
||||||
|
Contains("mybranch"),
|
||||||
|
Contains("worktree2 (worktree)"),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Views().Worktrees().
|
||||||
|
Focus().
|
||||||
|
Lines(
|
||||||
|
Contains("repo").IsSelected(),
|
||||||
|
Contains("worktree2"),
|
||||||
|
).
|
||||||
|
NavigateToLine(Contains("worktree2")).
|
||||||
|
Press(keys.Universal.Select).
|
||||||
|
Lines(
|
||||||
|
Contains("worktree2").IsSelected(),
|
||||||
|
Contains("repo"),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
Loading…
Add table
Add a link
Reference in a new issue