mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 15:46:26 -04:00
Lazygit changes the process working directory when switching repos, but work that is still in flight for the previous repo can keep spawning git commands after the switch — most notably a background refresh. Its model writes are already dropped by the repo generation guard, but its git commands would now run against the new repo. That is wasted work at best; at worst it surfaces spurious error popups (the behind-base- branch computation failing with "no such ref" when the old repo's main branch doesn't exist in the new one) and pollutes caches belonging to the old repo's reusable state (e.g. MainBranches' existing-branches cache), which the user sees when switching back. Give the git command builder the directory of the repo it was created for, and pin every command it produces to that directory. The pinned directory and the process cwd are identical until a switch happens (NewGitCommand chdirs to the worktree path right before creating the builder), so nothing changes in the steady state; the pin only takes effect for commands built through a previous repo's GitCommand instance after a switch, which now keep addressing the repo they were built for. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
42 lines
1.6 KiB
Go
42 lines
1.6 KiB
Go
package commands
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// Every git command we build disables optional locks by default, so that our
|
|
// invocations never contend for index.lock (see git_commands.OptionalLocksEnvVar
|
|
// for the rationale). Commands that want the lock opt back in with
|
|
// CmdObj.RemoveEnvVar.
|
|
func TestGitCmdObjBuilderDisablesOptionalLocksByDefault(t *testing.T) {
|
|
builder := NewGitCmdObjBuilder(
|
|
utils.NewDummyLog(),
|
|
oscommands.NewDummyCmdObjBuilder(oscommands.NewFakeRunner(t)),
|
|
"/path/to/repo",
|
|
)
|
|
|
|
assert.Contains(t, builder.New([]string{"git", "status"}).GetEnvVars(), git_commands.OptionalLocksEnvVar+"=0")
|
|
assert.Contains(t, builder.NewShell("git status", "").GetEnvVars(), git_commands.OptionalLocksEnvVar+"=0")
|
|
}
|
|
|
|
// Every command the builder produces runs in the directory of the repo the
|
|
// builder was created for, not in the process's current directory: lazygit
|
|
// chdirs when switching repos, and commands built for the previous repo after
|
|
// that (e.g. by a background refresh still in flight) must keep addressing the
|
|
// repo they were built for.
|
|
func TestGitCmdObjBuilderPinsCommandsToRepoDir(t *testing.T) {
|
|
builder := NewGitCmdObjBuilder(
|
|
utils.NewDummyLog(),
|
|
oscommands.NewDummyCmdObjBuilder(oscommands.NewFakeRunner(t)),
|
|
"/path/to/repo",
|
|
)
|
|
|
|
assert.Equal(t, "/path/to/repo", builder.New([]string{"git", "status"}).GetCmd().Dir)
|
|
assert.Equal(t, "/path/to/repo", builder.NewShell("git status", "").GetCmd().Dir)
|
|
}
|