fix(polecat): ensure nuke fully removes worktrees and branches

Two issues fixed:

1. Worktree directory cleanup used os.Remove() which only removes empty
   directories. Changed to os.RemoveAll() to clean up untracked files
   left behind by git worktree remove (overlay files, .beads/, etc.)

2. Branch deletion hardcoded mayor/rig but worktrees are created from
   .repo.git when using bare repo architecture. Now checks for bare
   repo first to match where the branch was created.

Fixes: gt-6ab3cm

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gastown/crew/george
2026-01-17 00:37:51 -08:00
committed by beads/crew/emma
parent d8bb9a9ba9
commit 0cc4867ad7
2 changed files with 15 additions and 12 deletions

View File

@@ -1203,8 +1203,15 @@ func runPolecatNuke(cmd *cobra.Command, args []string) error {
}
// Step 4: Delete branch (if we know it)
// Use bare repo if it exists (matches where worktree was created), otherwise mayor/rig
if branchToDelete != "" {
repoGit := git.NewGit(filepath.Join(p.r.Path, "mayor", "rig"))
var repoGit *git.Git
bareRepoPath := filepath.Join(p.r.Path, ".repo.git")
if info, err := os.Stat(bareRepoPath); err == nil && info.IsDir() {
repoGit = git.NewGitWithDir(bareRepoPath, "")
} else {
repoGit = git.NewGit(filepath.Join(p.r.Path, "mayor", "rig"))
}
if err := repoGit.DeleteBranch(branchToDelete, true); err != nil {
// Non-fatal - branch might already be gone
fmt.Printf(" %s branch delete: %v\n", style.Dim.Render("○"), err)

View File

@@ -445,21 +445,17 @@ func (m *Manager) RemoveWithOptions(name string, force, nuclear bool) error {
}
} else {
// GT-1L3MY9: git worktree remove may leave untracked directories behind.
// Clean up any leftover .beads/ directory that wasn't fully removed.
cloneBeadsDir := filepath.Join(clonePath, ".beads")
_ = os.RemoveAll(cloneBeadsDir)
// Remove the now-empty clonePath if it still exists
_ = os.Remove(clonePath)
// Clean up any leftover files (overlay files, .beads/, setup hook outputs, etc.)
// Use RemoveAll to handle non-empty directories with untracked files.
_ = os.RemoveAll(clonePath)
}
// Also remove the parent polecat directory if it's now empty
// Also remove the parent polecat directory
// (for new structure: polecats/<name>/ contains only polecats/<name>/<rigname>/)
if polecatDir != clonePath {
// GT-1L3MY9: Clean up any orphaned .beads/ directory at polecat level.
// This can happen if the worktree cleanup was incomplete or from old state.
polecatBeadsDir := filepath.Join(polecatDir, ".beads")
_ = os.RemoveAll(polecatBeadsDir)
_ = os.Remove(polecatDir) // Non-fatal: only removes if empty
// GT-1L3MY9: Clean up any orphaned files at polecat level.
// Use RemoveAll to handle non-empty directories with leftover files.
_ = os.RemoveAll(polecatDir)
}
// Prune any stale worktree entries (non-fatal: cleanup only)