Files
wild-cloud/tools/remove_worktree.py

93 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""
Remove a git worktree and optionally delete the associated branch.
Usage:
python tools/remove_worktree.py feature-branch
python tools/remove_worktree.py feature-branch --force
"""
import argparse
import subprocess
import sys
from pathlib import Path
def run_git_command(cmd: list[str]) -> tuple[int, str, str]:
"""Run a git command and return exit code, stdout, stderr."""
result = subprocess.run(cmd, capture_output=True, text=True)
return result.returncode, result.stdout.strip(), result.stderr.strip()
def main():
parser = argparse.ArgumentParser(description="Remove a git worktree and optionally delete its branch")
parser.add_argument("branch", help="Name of the branch/worktree to remove")
parser.add_argument("--force", action="store_true", help="Force removal even with uncommitted changes")
args = parser.parse_args()
# Get the base repository name
current_dir = Path.cwd()
repo_name = current_dir.name
# Construct worktree path (same pattern as create_worktree.py)
worktree_path = current_dir.parent / f"{repo_name}-{args.branch}"
print(f"Looking for worktree at: {worktree_path}")
# Check if worktree exists
returncode, stdout, _ = run_git_command(["git", "worktree", "list"])
if returncode != 0:
print("Error: Failed to list worktrees")
sys.exit(1)
worktree_exists = str(worktree_path) in stdout
if not worktree_exists:
print(f"Error: Worktree for branch '{args.branch}' not found at {worktree_path}")
sys.exit(1)
# Remove the worktree
remove_cmd = ["git", "worktree", "remove", str(worktree_path)]
if args.force:
remove_cmd.append("--force")
print(f"Removing worktree at {worktree_path}...")
returncode, stdout, stderr = run_git_command(remove_cmd)
if returncode != 0:
if "contains modified or untracked files" in stderr:
print("Error: Worktree contains uncommitted changes. Use --force to override.")
else:
print(f"Error removing worktree: {stderr}")
sys.exit(1)
print(f"Successfully removed worktree at {worktree_path}")
# Try to delete the branch
print(f"Attempting to delete branch '{args.branch}'...")
# Check current branch
returncode, current_branch, _ = run_git_command(["git", "branch", "--show-current"])
if returncode == 0 and current_branch == args.branch:
print(f"Cannot delete branch '{args.branch}' - it is currently checked out")
return
# Try to delete the branch
returncode, stdout, stderr = run_git_command(["git", "branch", "-d", args.branch])
if returncode == 0:
print(f"Successfully deleted branch '{args.branch}'")
elif "not fully merged" in stderr:
# Try force delete if regular delete fails due to unmerged changes
print("Branch has unmerged changes, force deleting...")
returncode, stdout, stderr = run_git_command(["git", "branch", "-D", args.branch])
if returncode == 0:
print(f"Successfully force-deleted branch '{args.branch}'")
else:
print(f"Warning: Could not delete branch: {stderr}")
else:
print(f"Warning: Could not delete branch: {stderr}")
if __name__ == "__main__":
main()