Delete the right git dir when removing a submodule in a linked worktree

Removing a submodule in a linked worktree deletes the git dir of that
submodule in the main worktree. This breaks the submodule there, and
any unpushed commits, local branches and stashes in it are lost. The
git dir of the submodule in the linked worktree stays behind.

Git keeps the git dirs of submodules separately for each worktree. For
a linked worktree, they are in .git/worktrees/<worktree>/modules.
Lazygit used the worktree's git dir until 3b723282cb switched it to the
repo's git dir, so this has been broken since v0.41.0. Use the
worktree's git dir again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-11-07 23:46:56 +01:00
co-authored by Claude Opus 5.5
parent 58fcd14a99
commit 98ca24de23
3 changed files with 5 additions and 10 deletions
+2 -3
View File
@@ -269,9 +269,8 @@ func (self *SubmoduleCommands) Delete(submodule *models.SubmoduleConfig) error {
self.Log.Error(err)
}
// We may in fact want to use the repo's git dir path but git docs say not to
// mix submodules and worktrees anyway.
return os.RemoveAll(submodule.GitDirPath(self.repoPaths.repoGitDirPath))
// Git keeps the git dirs of submodules separately for each worktree
return os.RemoveAll(submodule.GitDirPath(self.repoPaths.WorktreeGitDirPath()))
}
func (self *SubmoduleCommands) Add(name string, path string, url string) error {
+3 -3
View File
@@ -38,10 +38,10 @@ func (r *SubmoduleConfig) Description() string {
return r.RefName()
}
func (r *SubmoduleConfig) GitDirPath(repoGitDirPath string) string {
parentPath := repoGitDirPath
func (r *SubmoduleConfig) GitDirPath(worktreeGitDirPath string) string {
parentPath := worktreeGitDirPath
if r.ParentModule != nil {
parentPath = r.ParentModule.GitDirPath(repoGitDirPath)
parentPath = r.ParentModule.GitDirPath(worktreeGitDirPath)
}
return filepath.Join(parentPath, "modules", r.Name)
@@ -42,11 +42,7 @@ var RemoveInLinkedWorktree = NewIntegrationTest(NewIntegrationTestArgs{
IsEmpty()
t.FileSystem().
/* EXPECTED:
PathPresent(mainGitDirSubmodulePath).
PathNotPresent(linkedGitDirSubmodulePath)
ACTUAL: */
PathNotPresent(mainGitDirSubmodulePath).
PathPresent(linkedGitDirSubmodulePath)
},
})