mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-17 00:18:05 +02:00
Optimize number of early calls to GetRepoPaths
This change reduces the number of calls during application startup to one, calling GetRepoPaths() earlier than previously and plumbing the repoPaths struct around to achieve this end.
This commit is contained in:
@ -2,6 +2,7 @@ package git_commands
|
||||
|
||||
import (
|
||||
ioFs "io/fs"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@ -18,6 +19,7 @@ type RepoPaths struct {
|
||||
repoPath string
|
||||
repoGitDirPath string
|
||||
repoName string
|
||||
isBareRepo bool
|
||||
}
|
||||
|
||||
var gitPathFormatVersion GitVersion = GitVersion{2, 31, 0, ""}
|
||||
@ -54,6 +56,10 @@ func (self *RepoPaths) RepoName() string {
|
||||
return self.repoName
|
||||
}
|
||||
|
||||
func (self *RepoPaths) IsBareRepo() bool {
|
||||
return self.isBareRepo
|
||||
}
|
||||
|
||||
// Returns the repo paths for a typical repo
|
||||
func MockRepoPaths(currentPath string) *RepoPaths {
|
||||
return &RepoPaths{
|
||||
@ -62,6 +68,7 @@ func MockRepoPaths(currentPath string) *RepoPaths {
|
||||
repoPath: currentPath,
|
||||
repoGitDirPath: path.Join(currentPath, ".git"),
|
||||
repoName: "lazygit",
|
||||
isBareRepo: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +76,19 @@ func GetRepoPaths(
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
version *GitVersion,
|
||||
) (*RepoPaths, error) {
|
||||
gitDirOutput, err := callGitRevParse(cmd, version, "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree")
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetRepoPathsForDir(cwd, cmd, version)
|
||||
}
|
||||
|
||||
func GetRepoPathsForDir(
|
||||
dir string,
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
version *GitVersion,
|
||||
) (*RepoPaths, error) {
|
||||
gitDirOutput, err := callGitRevParseWithDir(cmd, version, dir, "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -84,13 +103,14 @@ func GetRepoPaths(
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
isBareRepo := gitDirResults[3] == "true"
|
||||
|
||||
// If we're in a submodule, --show-superproject-working-tree will return
|
||||
// a value, meaning gitDirResults will be length 4. In that case
|
||||
// a value, meaning gitDirResults will be length 5. In that case
|
||||
// return the worktree path as the repoPath. Otherwise we're in a
|
||||
// normal repo or a worktree so return the parent of the git common
|
||||
// dir (repoGitDirPath)
|
||||
isSubmodule := len(gitDirResults) == 4
|
||||
isSubmodule := len(gitDirResults) == 5
|
||||
|
||||
var repoPath string
|
||||
if isSubmodule {
|
||||
@ -106,17 +126,10 @@ func GetRepoPaths(
|
||||
repoPath: repoPath,
|
||||
repoGitDirPath: repoGitDirPath,
|
||||
repoName: repoName,
|
||||
isBareRepo: isBareRepo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func callGitRevParse(
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
version *GitVersion,
|
||||
gitRevArgs ...string,
|
||||
) (string, error) {
|
||||
return callGitRevParseWithDir(cmd, version, "", gitRevArgs...)
|
||||
}
|
||||
|
||||
func callGitRevParseWithDir(
|
||||
cmd oscommands.ICmdObjBuilder,
|
||||
version *GitVersion,
|
||||
|
@ -36,10 +36,12 @@ func TestGetRepoPaths(t *testing.T) {
|
||||
"/path/to/repo/.git",
|
||||
// --git-common-dir
|
||||
"/path/to/repo/.git",
|
||||
// --is-bare-repository
|
||||
"false",
|
||||
// --show-superproject-working-tree
|
||||
}
|
||||
runner.ExpectGitArgs(
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
||||
strings.Join(expectedOutput, "\n"),
|
||||
nil)
|
||||
},
|
||||
@ -50,6 +52,38 @@ func TestGetRepoPaths(t *testing.T) {
|
||||
repoPath: "/path/to/repo",
|
||||
repoGitDirPath: "/path/to/repo/.git",
|
||||
repoName: "repo",
|
||||
isBareRepo: false,
|
||||
},
|
||||
Err: nil,
|
||||
},
|
||||
{
|
||||
Name: "bare repo",
|
||||
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
||||
// setup for main worktree
|
||||
expectedOutput := []string{
|
||||
// --show-toplevel
|
||||
"/path/to/repo",
|
||||
// --git-dir
|
||||
"/path/to/bare_repo/bare.git",
|
||||
// --git-common-dir
|
||||
"/path/to/bare_repo/bare.git",
|
||||
// --is-bare-repository
|
||||
"true",
|
||||
// --show-superproject-working-tree
|
||||
}
|
||||
runner.ExpectGitArgs(
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
||||
strings.Join(expectedOutput, "\n"),
|
||||
nil)
|
||||
},
|
||||
Path: "/path/to/repo",
|
||||
Expected: &RepoPaths{
|
||||
worktreePath: "/path/to/repo",
|
||||
worktreeGitDirPath: "/path/to/bare_repo/bare.git",
|
||||
repoPath: "/path/to/bare_repo",
|
||||
repoGitDirPath: "/path/to/bare_repo/bare.git",
|
||||
repoName: "bare_repo",
|
||||
isBareRepo: true,
|
||||
},
|
||||
Err: nil,
|
||||
},
|
||||
@ -63,11 +97,13 @@ func TestGetRepoPaths(t *testing.T) {
|
||||
"/path/to/repo/.git/modules/submodule1",
|
||||
// --git-common-dir
|
||||
"/path/to/repo/.git/modules/submodule1",
|
||||
// --is-bare-repository
|
||||
"false",
|
||||
// --show-superproject-working-tree
|
||||
"/path/to/repo",
|
||||
}
|
||||
runner.ExpectGitArgs(
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
||||
strings.Join(expectedOutput, "\n"),
|
||||
nil)
|
||||
},
|
||||
@ -78,6 +114,7 @@ func TestGetRepoPaths(t *testing.T) {
|
||||
repoPath: "/path/to/repo/submodule1",
|
||||
repoGitDirPath: "/path/to/repo/.git/modules/submodule1",
|
||||
repoName: "submodule1",
|
||||
isBareRepo: false,
|
||||
},
|
||||
Err: nil,
|
||||
},
|
||||
@ -85,7 +122,7 @@ func TestGetRepoPaths(t *testing.T) {
|
||||
Name: "git rev-parse returns an error",
|
||||
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
|
||||
runner.ExpectGitArgs(
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
|
||||
append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
|
||||
"",
|
||||
errors.New("fatal: invalid gitfile format: /path/to/repo/worktree2/.git"))
|
||||
},
|
||||
@ -94,7 +131,7 @@ func TestGetRepoPaths(t *testing.T) {
|
||||
Err: func(getRevParseArgs argFn) error {
|
||||
args := strings.Join(getRevParseArgs(), " ")
|
||||
return errors.New(
|
||||
fmt.Sprintf("'git %v --show-toplevel --absolute-git-dir --git-common-dir --show-superproject-working-tree' failed: fatal: invalid gitfile format: /path/to/repo/worktree2/.git", args),
|
||||
fmt.Sprintf("'git %v --show-toplevel --absolute-git-dir --git-common-dir --is-bare-repository --show-superproject-working-tree' failed: fatal: invalid gitfile format: /path/to/repo/worktree2/.git", args),
|
||||
)
|
||||
},
|
||||
},
|
||||
@ -120,7 +157,7 @@ func TestGetRepoPaths(t *testing.T) {
|
||||
// prepare the filesystem for the scenario
|
||||
s.BeforeFunc(runner, getRevParseArgs)
|
||||
|
||||
repoPaths, err := GetRepoPaths(cmd, version)
|
||||
repoPaths, err := GetRepoPathsForDir("", cmd, version)
|
||||
|
||||
// check the error and the paths
|
||||
if s.Err != nil {
|
||||
|
@ -3,10 +3,8 @@ package git_commands
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
|
||||
)
|
||||
|
||||
@ -49,20 +47,8 @@ func (self *StatusCommands) WorkingTreeState() enums.RebaseMode {
|
||||
return enums.REBASE_MODE_NONE
|
||||
}
|
||||
|
||||
func (self *StatusCommands) IsBareRepo() (bool, error) {
|
||||
return IsBareRepo(self.os)
|
||||
}
|
||||
|
||||
func IsBareRepo(osCommand *oscommands.OSCommand) (bool, error) {
|
||||
res, err := osCommand.Cmd.New(
|
||||
NewGitCmd("rev-parse").Arg("--is-bare-repository").ToArgv(),
|
||||
).DontLog().RunWithOutput()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// The command returns output with a newline, so we need to strip
|
||||
return strconv.ParseBool(strings.TrimSpace(res))
|
||||
func (self *StatusCommands) IsBareRepo() bool {
|
||||
return self.repoPaths.isBareRepo
|
||||
}
|
||||
|
||||
func (self *StatusCommands) IsInNormalRebase() (bool, error) {
|
||||
|
Reference in New Issue
Block a user