diff --git a/internal/git/worktree.go b/internal/git/worktree.go index 754ec92d..bd0e011f 100644 --- a/internal/git/worktree.go +++ b/internal/git/worktree.go @@ -321,14 +321,15 @@ func (wm *WorktreeManager) mergeJSONLFiles(srcData, dstData []byte) ([]byte, err } -// normalizeBeadsRelPath strips any leading path components before .beads. +// normalizeBeadsRelPath strips any leading path components before .beads/. // This handles bare repo worktrees where the relative path includes the worktree // name (e.g., "main/.beads/issues.jsonl" -> ".beads/issues.jsonl"). // GH#785: Fix for sync failing across worktrees in bare repo setup. func normalizeBeadsRelPath(relPath string) string { // Use filepath.ToSlash for consistent handling across platforms normalized := filepath.ToSlash(relPath) - if idx := strings.Index(normalized, ".beads"); idx > 0 { + // Look for ".beads/" to ensure we match the directory, not a prefix like ".beads-backup" + if idx := strings.Index(normalized, ".beads/"); idx > 0 { // Strip leading path components before .beads return filepath.FromSlash(normalized[idx:]) } diff --git a/internal/syncbranch/worktree.go b/internal/syncbranch/worktree.go index 7ab233fe..d5956b99 100644 --- a/internal/syncbranch/worktree.go +++ b/internal/syncbranch/worktree.go @@ -1082,14 +1082,15 @@ func formatVanishedIssues(localIssues, mergedIssues map[string]issueSummary, loc return lines } -// normalizeBeadsRelPath strips any leading path components before .beads. +// normalizeBeadsRelPath strips any leading path components before .beads/. // This handles bare repo worktrees where the relative path includes the worktree // name (e.g., "main/.beads/issues.jsonl" -> ".beads/issues.jsonl"). // GH#785: Fix for sync failing across worktrees in bare repo setup. func normalizeBeadsRelPath(relPath string) string { // Use filepath.ToSlash for consistent handling across platforms normalized := filepath.ToSlash(relPath) - if idx := strings.Index(normalized, ".beads"); idx > 0 { + // Look for ".beads/" to ensure we match the directory, not a prefix like ".beads-backup" + if idx := strings.Index(normalized, ".beads/"); idx > 0 { // Strip leading path components before .beads return filepath.FromSlash(normalized[idx:]) } diff --git a/internal/syncbranch/worktree_path_test.go b/internal/syncbranch/worktree_path_test.go index 77d973de..6904d45b 100644 --- a/internal/syncbranch/worktree_path_test.go +++ b/internal/syncbranch/worktree_path_test.go @@ -218,6 +218,16 @@ func TestNormalizeBeadsRelPath(t *testing.T) { input: ".beads/subdir/file.jsonl", expected: ".beads/subdir/file.jsonl", }, + { + name: "similar prefix like .beads-backup not matched", + input: "foo/.beads-backup/.beads/issues.jsonl", + expected: ".beads/issues.jsonl", + }, + { + name: "only .beads-backup no real .beads unchanged", + input: "foo/.beads-backup/file.txt", + expected: "foo/.beads-backup/file.txt", + }, } for _, tt := range tests {