mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Identify the current and main worktree by git dir, not by path
`git worktree list` reports the main worktree as the common git dir with a trailing "/.git" removed, which equals the working tree only when the git dir sits inside it. In a submodule, a bare repo, or a repo using core.worktree it doesn't, so comparing the reported path against the working tree path matches nothing: no worktree is recognized as current or as main. Most visibly, inside a submodule lazygit claimed we were in a linked worktree named after the submodule, and offered to remove that "worktree". Comparing git dirs identifies a worktree unambiguously, so use that. A worktree whose directory is gone has no git dir to compare, and there we still have nothing better than its path. The submodule tests were asserting the linked-worktree suffix in the status view; it is gone now, and the repo name still says which submodule we're in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e1b8ef048a
commit
d2d5bdc2bc
|
|
@ -22,9 +22,6 @@ func NewWorktreeLoader(gitCommon *GitCommon) *WorktreeLoader {
|
|||
}
|
||||
|
||||
func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
|
||||
currentRepoPath := self.repoPaths.RepoPath()
|
||||
worktreePath := self.repoPaths.WorktreePath()
|
||||
|
||||
cmdArgs := NewGitCmd("worktree").Arg("list", "--porcelain").ToArgv()
|
||||
worktreesOutput, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
|
||||
if err != nil {
|
||||
|
|
@ -54,17 +51,13 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
|
|||
|
||||
if strings.HasPrefix(splitLine, "worktree ") {
|
||||
path := strings.SplitN(splitLine, " ", 2)[1]
|
||||
isMain := path == currentRepoPath
|
||||
isCurrent := path == worktreePath
|
||||
isPathMissing := self.pathExists(path)
|
||||
|
||||
current = &models.Worktree{
|
||||
IsMain: isMain,
|
||||
IsCurrent: isCurrent,
|
||||
IsPathMissing: isPathMissing,
|
||||
IsPathMissing: self.pathExists(path),
|
||||
Path: path,
|
||||
// we defer populating GitDir until a loop below so that
|
||||
// we can parallelize the calls to git rev-parse
|
||||
// we can parallelize the calls to git rev-parse, and
|
||||
// IsMain/IsCurrent because they are derived from GitDir
|
||||
GitDir: "",
|
||||
}
|
||||
} else if strings.HasPrefix(splitLine, "HEAD ") {
|
||||
|
|
@ -95,6 +88,23 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
|
|||
}
|
||||
wg.Wait()
|
||||
|
||||
// Identify the current and the main worktree by their git dir rather than by
|
||||
// their path: `git worktree list` reports the main worktree as the common
|
||||
// git dir with a trailing "/.git" removed, which is the working tree only
|
||||
// when the git dir sits inside it. In a submodule, a bare repo or a repo
|
||||
// using core.worktree it doesn't, and comparing paths then matches nothing.
|
||||
// A worktree whose directory is gone has no git dir to compare, so there we
|
||||
// have nothing better than its path.
|
||||
for _, worktree := range worktrees {
|
||||
if worktree.GitDir != "" {
|
||||
worktree.IsCurrent = worktree.GitDir == self.repoPaths.WorktreeGitDirPath()
|
||||
worktree.IsMain = worktree.GitDir == self.repoPaths.RepoGitDirPath()
|
||||
} else {
|
||||
worktree.IsCurrent = worktree.Path == self.repoPaths.WorktreePath()
|
||||
worktree.IsMain = worktree.Path == self.repoPaths.RepoPath()
|
||||
}
|
||||
}
|
||||
|
||||
names := getUniqueNamesFromPaths(lo.Map(worktrees, func(worktree *models.Worktree, _ int) string {
|
||||
return worktree.Path
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -218,12 +218,8 @@ branch refs/heads/mybranch
|
|||
},
|
||||
expectedWorktrees: []*models.Worktree{
|
||||
{
|
||||
/* EXPECTED:
|
||||
IsMain: true,
|
||||
IsCurrent: true,
|
||||
ACTUAL: */
|
||||
IsMain: false,
|
||||
IsCurrent: false,
|
||||
Path: "/path/to/repo/.git/modules/mysubmodule",
|
||||
IsPathMissing: false,
|
||||
GitDir: "/path/to/repo/.git/modules/mysubmodule",
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ var Enter = NewIntegrationTest(NewIntegrationTestArgs{
|
|||
t.Views().Status().Content(Contains("repo"))
|
||||
}
|
||||
assertInSubmodule := func() {
|
||||
t.Views().Status().Content(Contains("my_submodule_path(my_submodule_name)"))
|
||||
t.Views().Status().Content(Contains("my_submodule_path"))
|
||||
}
|
||||
|
||||
assertInParentRepo()
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ var EnterNested = NewIntegrationTest(NewIntegrationTestArgs{
|
|||
// enter the nested submodule
|
||||
PressEnter()
|
||||
|
||||
t.Views().Status().Content(Contains("innerSubPath(innerSubName)"))
|
||||
t.Views().Status().Content(Contains("innerSubPath"))
|
||||
t.Views().Commits().ContainsLines(
|
||||
Contains("initial inner commit"),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{
|
|||
t.Views().Status().Content(Contains("repo"))
|
||||
}
|
||||
assertInSubmodule := func() {
|
||||
t.Views().Status().Content(Contains("my_submodule_path(my_submodule_name)"))
|
||||
t.Views().Status().Content(Contains("my_submodule_path"))
|
||||
}
|
||||
|
||||
assertInParentRepo()
|
||||
|
|
|
|||
Loading…
Reference in a new issue