mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-08-24 10:13:41 -05:00
Pin the cached git config's commands to the repo directory
The cached git config runs its `git config` reads through raw exec.Command calls, outside the pinned git command builder, so they followed the process working directory. A cache miss on a stale instance — one still in use by a refresh that crossed a repo switch — would therefore read the new repo's local config while computing data for the old one. Give the cache a directory, set once by NewGitCommand right after it determines the repo paths (the object is created fresh for every repo switch, so no cross-repo cache invalidation is needed), and run every config command there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
e0b8dbf48c
commit
568a4276d7
@@ -72,6 +72,10 @@ func NewGitCommand(
|
||||
return nil, utils.WrapError(err)
|
||||
}
|
||||
|
||||
// Pin the config reads to the repo directory like all other git commands
|
||||
// (see NewGitCmdObjBuilder); the config commands run outside that builder.
|
||||
gitConfig.SetDir(repoPaths.WorktreePath())
|
||||
|
||||
return NewGitCommandAux(
|
||||
cmn,
|
||||
version,
|
||||
|
||||
@@ -16,11 +16,19 @@ type IGitConfig interface {
|
||||
// this is for when you want to pass 'mykey' and check if the result is truthy
|
||||
GetBool(string) bool
|
||||
|
||||
// SetDir pins the config commands to the given repo directory, so that
|
||||
// they keep reading that repo's local config even if the process working
|
||||
// directory changes later (i.e. the user switches repos while this
|
||||
// instance is still in use by in-flight work). Called once, before the
|
||||
// first read.
|
||||
SetDir(string)
|
||||
|
||||
DropCache()
|
||||
}
|
||||
|
||||
type CachedGitConfig struct {
|
||||
cache map[string]string
|
||||
dir string
|
||||
runGitConfigCmd func(*exec.Cmd) (string, error)
|
||||
log *logrus.Entry
|
||||
mutex sync.Mutex
|
||||
@@ -39,6 +47,13 @@ func NewCachedGitConfig(runGitConfigCmd func(*exec.Cmd) (string, error), log *lo
|
||||
}
|
||||
}
|
||||
|
||||
func (self *CachedGitConfig) SetDir(dir string) {
|
||||
self.mutex.Lock()
|
||||
defer self.mutex.Unlock()
|
||||
|
||||
self.dir = dir
|
||||
}
|
||||
|
||||
func (self *CachedGitConfig) Get(key string) string {
|
||||
self.mutex.Lock()
|
||||
defer self.mutex.Unlock()
|
||||
@@ -69,6 +84,7 @@ func (self *CachedGitConfig) GetGeneral(args string) string {
|
||||
|
||||
func (self *CachedGitConfig) getGeneralAux(args string) string {
|
||||
cmd := getGitConfigGeneralCmd(args)
|
||||
cmd.Dir = self.dir
|
||||
value, err := self.runGitConfigCmd(cmd)
|
||||
if err != nil {
|
||||
self.log.Debugf("Error getting git config value for args: %s. Error: %v", args, err.Error())
|
||||
@@ -79,6 +95,7 @@ func (self *CachedGitConfig) getGeneralAux(args string) string {
|
||||
|
||||
func (self *CachedGitConfig) getAux(key string) string {
|
||||
cmd := getGitConfigCmd(key)
|
||||
cmd.Dir = self.dir
|
||||
value, err := self.runGitConfigCmd(cmd)
|
||||
if err != nil {
|
||||
self.log.Debugf("Error getting git config value for key: %s. Error: %v", key, err.Error())
|
||||
|
||||
@@ -116,3 +116,20 @@ func TestGet(t *testing.T) {
|
||||
assert.Equal(t, "blah", result)
|
||||
assert.Equal(t, 1, count)
|
||||
}
|
||||
|
||||
// The config commands run in the directory set by SetDir rather than in the
|
||||
// process's current directory: lazygit chdirs when switching repos, and config
|
||||
// reads issued for the previous repo after that must keep addressing the repo
|
||||
// they were created for.
|
||||
func TestSetDirPinsCommandsToDirectory(t *testing.T) {
|
||||
real := NewCachedGitConfig(
|
||||
func(cmd *exec.Cmd) (string, error) {
|
||||
assert.Equal(t, "/path/to/repo", cmd.Dir)
|
||||
return "blah", nil
|
||||
},
|
||||
utils.NewDummyLog(),
|
||||
)
|
||||
real.SetDir("/path/to/repo")
|
||||
real.Get("commit.gpgsign")
|
||||
real.GetGeneral("--local --get-regexp foo")
|
||||
}
|
||||
|
||||
@@ -28,5 +28,8 @@ func (self *FakeGitConfig) GetBool(key string) bool {
|
||||
return isTruthy(self.Get(key))
|
||||
}
|
||||
|
||||
func (self *FakeGitConfig) SetDir(dir string) {
|
||||
}
|
||||
|
||||
func (self *FakeGitConfig) DropCache() {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user