fix(done): auto-detect cleanup status to prevent premature nuke (#361)

When polecats run 'gt done' without --cleanup-status, the witness may
prematurely nuke the worktree before the refinery can merge.

This fix auto-detects git state:
- uncommitted: has uncommitted changes
- stash: has stashed changes
- unpushed: branch not pushed or has unpushed commits
- clean: everything pushed

Uses BranchPushedToRemote() which properly handles polecat branches
that don't have upstream tracking (compares against origin/main).
On error, defaults to 'unpushed' to prevent accidental data loss.

Fixes: #342

Co-authored-by: mayor <mayor@gastown.local>
This commit is contained in:
Steve Brown
2026-01-11 21:47:49 -05:00
committed by GitHub
parent 7ef4ddab6c
commit 91641b01a0

View File

@@ -119,6 +119,35 @@ func runDone(cmd *cobra.Command, args []string) error {
return fmt.Errorf("getting current branch: %w", err)
}
// Auto-detect cleanup status if not explicitly provided
// This prevents premature polecat cleanup by ensuring witness knows git state
if doneCleanupStatus == "" {
workStatus, err := g.CheckUncommittedWork()
if err != nil {
style.PrintWarning("could not auto-detect cleanup status: %v", err)
} else {
switch {
case workStatus.HasUncommittedChanges:
doneCleanupStatus = "uncommitted"
case workStatus.StashCount > 0:
doneCleanupStatus = "stash"
default:
// CheckUncommittedWork.UnpushedCommits doesn't work for branches
// without upstream tracking (common for polecats). Use the more
// robust BranchPushedToRemote which compares against origin/main.
pushed, unpushedCount, err := g.BranchPushedToRemote(branch, "origin")
if err != nil {
style.PrintWarning("could not check if branch is pushed: %v", err)
doneCleanupStatus = "unpushed" // err on side of caution
} else if !pushed || unpushedCount > 0 {
doneCleanupStatus = "unpushed"
} else {
doneCleanupStatus = "clean"
}
}
}
}
// Parse branch info
info := parseBranchName(branch)