Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/worktree.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ func init() {
wtPruneCmd.Flags().StringVarP(&wtPruneBase, "base", "b", "", "Base branch to check merge status against")
wtPruneCmd.Flags().BoolVarP(&wtPruneForce, "force", "f", false, "Force removal even if worktree is dirty")
wtPruneCmd.Flags().BoolVar(&wtPruneDryRun, "dry-run", false, "Preview what would be removed without making changes")
wtPruneCmd.Flags().BoolVar(&wtPrunePRAware, "pr-aware", false, "Check GitHub PR state before pruning (requires gh CLI)")

// Flags for pr-review command
wtPrReviewCmd.Flags().StringVarP(&prRemote, "remote", "r", "",
Expand Down
41 changes: 37 additions & 4 deletions cmd/worktree_prune.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package cmd

import (
"fmt"
"text/tabwriter"

"github.com/samzong/gmc/internal/worktree"
"github.com/spf13/cobra"
)

var (
wtPruneBase string
wtPruneForce bool
wtPruneDryRun bool
wtPruneBase string
wtPruneForce bool
wtPruneDryRun bool
wtPrunePRAware bool
)

var wtPruneCmd = &cobra.Command{
Expand All @@ -17,7 +21,10 @@ var wtPruneCmd = &cobra.Command{
Long: `Remove worktrees whose branches are already merged into the base branch.

This command uses pure git ancestry checks to decide which worktrees are safe to remove.
By default it removes both the worktree directory and the local branch.`,
By default it removes both the worktree directory and the local branch.

Use --pr-aware to check GitHub PR state (via gh CLI) before deciding whether
to remove each worktree. Only worktrees with MERGED PRs are removed.`,
RunE: func(_ *cobra.Command, _ []string) error {
wtClient := newWorktreeClient()
return runWorktreePrune(wtClient)
Expand All @@ -36,12 +43,17 @@ func runWorktreePrune(wtClient *worktree.Client) error {
BaseBranch: wtPruneBase,
Force: wtPruneForce,
DryRun: wtPruneDryRun,
PRAware: wtPrunePRAware,
}
result, err := wtClient.Prune(opts)
if err != nil {
return err
}

if outputFormat() == "json" {
if opts.PRAware {
return printJSON(outWriter(), result.PruneEntries)
}
action := "removed"
if opts.DryRun {
action = "would-remove"
Expand All @@ -57,6 +69,27 @@ func runWorktreePrune(wtClient *worktree.Client) error {
}
return printJSON(outWriter(), items)
}

printWorktreeReport(result.Report)
if len(result.PruneEntries) > 0 {
printPruneTable(result.PruneEntries)
}
return nil
}

func printPruneTable(entries []worktree.PruneEntry) {
w := tabwriter.NewWriter(outWriter(), 0, 0, 2, ' ', 0)
fmt.Fprintln(w, "NAME\tBRANCH\tPR\tPR STATE\tACTION\tREASON")
for _, e := range entries {
pr := "-"
if e.PRNum > 0 {
pr = fmt.Sprintf("#%d", e.PRNum)
}
state := e.PRState
if state == "" {
state = "none"
}
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", e.Name, e.Branch, pr, state, e.Action, e.Reason)
}
w.Flush()
}
Loading
Loading