Skip to content

prune command reports false success when branch deletion fails for squash-merged PRs #77

Description

@bjester

Observed Behavior

When worktrees associated with squash-merged GitHub pull requests are pruned, local branch deletion fails because git branch -d rejects branches whose commit history does not form a direct ancestry with the target branch. Despite this failure, _do_prune catches the exception, logs a warning, and returns True. The command summary then reports full success (1 pruned, 0 failed), misleading the user into believing the branch was removed when it was actually retained.

Expected Behavior

  1. Worktrees associated with merged pull requests (already cryptographically verified via GitHub PR headRefOid == local_head) should have their local branches deleted cleanly (or handle squash-merge semantics safely).
  2. If branch deletion fails, _do_prune must reflect the failure accurately, incrementing failed_count and reporting the failure in the final summary.

Steps to Reproduce

  1. In a repository, create and push a branch, open a PR, and squash-merge it on GitHub.
  2. In the local repository, run treefort prune.
  3. Confirm prompt (y).
  4. Git worktree directory is removed, but git.delete_branch executes git branch -d -- <branch>, which exits with non-zero status:
    error: The branch '<branch>' is not fully merged.
  5. _do_prune catches CommandError, logs warning Failed to delete branch '<branch>': ..., but still returns True.
  6. Command reports: Pruning complete: 1 pruned, 0 failed. Local branch still exists in git branch.

Minimal Reproduction Environment / Conditions

  • Version / Branch / Commit: release-v0.5.x@6d07c0c
  • Component: treefort.commands.prune.PruneCommand
  • Trigger: Any GitHub PR merged via "Squash and merge" (default GitHub merge method)

Errors, Logs & Telemetry

WARNING: Failed to delete branch 'feature-squashed': Command failed, with exit status 1: git branch -d -- feature-squashed
INFO: Successfully pruned 'feature-squashed'
INFO: Pruning complete: 1 pruned, 0 failed.

Deliverables & Testing Requirements

  • Address branch deletion for squash-merged PRs (once local_head == pr.headRefOid confirms the branch was merged into the PR, determine whether force deletion -D or prompt is appropriate).
  • Ensure failed_count increments when branch deletion fails, and avoid logging Successfully pruned when a core step of pruning fails.
  • Regression Safety: Add a unit test in tests/commands/test_prune.py asserting that _do_prune returns False or reports failure when delete_branch raises CommandError.

Technical Pointers & Root Cause Clues

  • Suspected Components: src/treefort/commands/prune.py:44-52, 119-132 (_do_prune and __call__), src/treefort/git.py:87-90 (delete_branch)
  • Related Commits: bd7ed4c (Add new prune command for removing worktrees for merged PR branches)

Notes & Edge Cases

  • Squash-merging is the predominant merge strategy on GitHub. Without addressing this, the majority of PRs pruned by users will leave stale branches behind.

Metadata

Severity / Priority: P0 (Blocker)
Area: bug, prune, git

AI Usage

Drafted with Gemini following the DEEP framework based on code review findings against release-v0.5.x. Reproduction conditions and code references were verified in the codebase.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0 - CriticalCritical release blocking issuesbugSomething isn't working

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions