fix: IsWorkingDirectoryClean to work correctly in worktrees

- Check filesystem existence of staged files to handle worktree scenarios
- Ignore files staged in main repo that don't exist in worktree
- Allow staged files that exist in worktree to be committed normally

Co-Authored-By: Warp <agent@warp.dev>
This commit is contained in:
Kayvan Sylvan
2026-01-03 14:16:09 -08:00
parent 11e9e16078
commit 53bad5b70d

View File

@@ -2,6 +2,8 @@ package git
import ( import (
"fmt" "fmt"
"os"
"path/filepath"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@@ -433,14 +435,27 @@ func (w *Walker) IsWorkingDirectoryClean() (bool, error) {
return false, fmt.Errorf("failed to get git status: %w", err) return false, fmt.Errorf("failed to get git status: %w", err)
} }
// In worktrees, we need to check if files are actually modified in the working directory worktreePath := worktree.Filesystem.Root()
// Ignore files that are only staged (Added) but not present in the worktree filesystem
for _, fileStatus := range status { // In worktrees, files staged in the main repo may appear in status but not exist in the worktree
// Check if there are any changes in the working directory (not just staging) // We need to check both the working directory status AND filesystem existence
// Worktree status codes: ' ' = unmodified, 'M' = modified, 'D' = deleted, '?' = untracked for file, fileStatus := range status {
// Check if there are any changes in the working directory
if fileStatus.Worktree != git.Unmodified && fileStatus.Worktree != git.Untracked { if fileStatus.Worktree != git.Unmodified && fileStatus.Worktree != git.Untracked {
return false, nil return false, nil
} }
// For staged files (Added, Modified in index), verify they exist in this worktree's filesystem
// This handles the worktree case where the main repo has staged files that don't exist here
if fileStatus.Staging != git.Unmodified && fileStatus.Staging != git.Untracked {
filePath := filepath.Join(worktreePath, file)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
// File is staged but doesn't exist in this worktree - ignore it
continue
}
// File is staged AND exists in this worktree - not clean
return false, nil
}
} }
return true, nil return true, nil