diff --git a/workspaces.py b/workspaces.py index e3a53d2..f7158bc 100755 --- a/workspaces.py +++ b/workspaces.py @@ -1315,118 +1315,6 @@ def diff_workspace( if not any_diffs: console.print("[green]No changes to diff in any repo.[/green]") -def get_branches_merged(repo_dir: Path, remote: bool = False, main_branch: str="main") -> list[str]: - cmd = ["git", "branch", "--merged", main_branch] - if remote: - cmd.append("--remotes") - branches = run_cmd(cmd, cwd=repo_dir) - current_branch = get_current_branch(repo_dir) - branches = [b.strip() for b in branches[1].splitlines() if not b.startswith("*") and not b.startswith("+")] - - branches = [ - b for b in branches - if b not in {main_branch, f"origin/{main_branch}", "origin/HEAD -> origin/main", current_branch} - and "->" not in b # filters symbolic refs - ] - return branches - - -@app.command("clean") -def clean_workspace( - ctx: typer.Context, - workspace: str | None = typer.Option( - None, - "--workspace", - "-w", - help=( - "Workspace directory name to diff. " - "If omitted, uses the workspace containing the current directory." - ), - ), - dry_run: bool = typer.Option( - False, - "--dry-run", - "-n", - help="Print what would be deleted, but don't actually delete.", - ), -): - """Show detailed status for the current (or specified) workspace. - - For each repo in the workspace: - - look up all local branches that are merged into main - - ask user to delete local branches that are merged into main - - look up all remote branches that are merged into main - - ask user to delete remote branches that are merged into main - """ - _settings, _repos_dir, workspaces_dir = get_ctx_paths(ctx) - ws_dir = find_workspace_dir(workspaces_dir, workspace) - workspace = ws_dir.name - - if not ws_dir: - console.print(f"[red]Workspace '{workspace}' does not exist at {ws_dir}[/red]") - raise typer.Exit(1) - repos = [directory for directory in ws_dir.iterdir() if directory.is_dir()] - repo = pick_repo_with_iterfzf(repos) - - title, _desc = read_workspace_readme(ws_dir) - console.print( - f"Cleaning workspace [bold]{title or ws_dir.name}[/bold] (dir: {repo.name})" - ) - - run_cmd(["git", "fetch", "--all", "--prune"], cwd=repo) - local_branches_merged = get_branches_merged(repo, remote=False) - remote_branches_merged = get_branches_merged(repo, remote=True) - - if len(local_branches_merged) == 0 and len(remote_branches_merged) == 0: - console.print("[green]No branches to delete.[/green]") - raise typer.Exit(0) - - console.print( - f"[green]Would delete {len(local_branches_merged)} local branches[/green]" - ) - for b in local_branches_merged: - console.print(f"[yellow]{b}[/yellow]") - console.print( - f"[green]Would delete {len(remote_branches_merged)} remote branches[/green]" - ) - for b in remote_branches_merged: - console.print(f"[yellow]{b}[/yellow]") - - if dry_run: - console.print("[grey]Dry run. Exiting.[/grey]") - raise typer.Exit(0) - - if not Confirm.ask("Delete these branches?"): - console.print("[red]Aborting.[/red]") - raise typer.Exit(1) - - for b in local_branches_merged: - cmd = ["git", "branch", "-D", b] - - run_cmd(cmd, cwd=repo) - - for b in remote_branches_merged: - # b looks like "origin/feat/workspaces-tmux-support" - if "->" in b: - # safety: skip symbolic refs like "origin/HEAD -> origin/main" - continue - - try: - remote, branch = b.split("/", 1) - except ValueError: - # fallback: no slash? assume origin + raw name - remote, branch = "origin", b - - cmd = ["git", "push", remote, "--delete", branch] - - status, out, err = run_cmd(cmd, cwd=repo) - - if status != 0: - console.print(f"[red]Failed to delete {remote}/{branch}:[/red]\n{err}") - continue - - console.print("[green]Done.[/green]") - def in_tmux() -> bool: """Return True if inside tmux"""