1use clap::Parser;
2
3#[derive(Parser)]
4pub struct Cli {
5 #[clap(subcommand)]
6 pub command: Commands,
7}
8
9#[derive(clap::Subcommand)]
10pub enum Commands {
11 #[clap(about = "Rename the current branch")]
12 RenameBranch {
13 #[clap(help = "New name for the current branch")]
14 new_name: String,
15 },
16 #[clap(about = "Delete merged local branches (except protected ones)")]
17 PruneBranches {
18 #[clap(
19 long = "except",
20 value_name = "branches",
21 help = "Comma-separated list of branches to exclude"
22 )]
23 except: Option<String>,
24 #[clap(long = "dry-run", help = "Show which branches would be deleted without actually deleting them", action = clap::ArgAction::SetTrue)]
25 dry_run: bool,
26 },
27 #[clap(about = "Show a high-level overview of the current repo")]
28 Info,
29 #[clap(about = "Pretty Git log with branches, remotes, and HEADs")]
30 Graph,
31 #[clap(about = "Colorized Git log with branches, remotes, and HEADs")]
32 ColorGraph,
33 #[clap(about = "Check repository health and show potential issues")]
34 Health,
35 #[clap(about = "Show commits since a reference (e.g., cb676ec, origin/main)")]
36 Since {
37 #[clap(help = "Reference point")]
38 reference: String,
39 },
40 #[clap(about = "Undo the last commit (without losing changes)")]
41 Undo,
42 #[clap(about = "Delete all fully merged local branches (except protected ones)")]
43 CleanBranches {
44 #[clap(long = "dry-run", help = "Prints the branches it would delete instead of actually deleting them", action = clap::ArgAction::SetTrue)]
45 dry_run: bool,
46 },
47 #[clap(about = "Show what’s different between this branch and another (default: main)")]
48 What {
49 #[clap(long = "target", help = "Branch to compare to")]
50 target: Option<String>,
51 },
52 #[clap(about = "Show a short, changelog-style summary of recent commits")]
53 Summary {
54 #[clap(
55 long = "since",
56 help = "Accepts flexible formats like \"yesterday\", \"3 days ago\", \"2025-07-01\", etc. (same as git log --since)"
57 )]
58 since: String,
59 },
60 #[clap(about = "Sync current branch with upstream (fetch + rebase)")]
61 Sync {
62 #[clap(long = "merge", help = "Use merge instead of rebase", action = clap::ArgAction::SetTrue)]
63 merge: bool,
64 },
65 #[clap(about = "Create and switch to a new branch")]
66 New {
67 #[clap(help = "Name of the new branch")]
68 branch_name: String,
69 #[clap(
70 long = "from",
71 help = "Base branch to create from (default: current branch)"
72 )]
73 from: Option<String>,
74 },
75 #[clap(about = "Find largest files in repository history")]
76 LargeFiles {
77 #[clap(long = "limit", default_value = "10", help = "Number of files to show")]
78 limit: usize,
79 #[clap(
80 long = "threshold",
81 help = "Minimum file size in MB (default: show all)"
82 )]
83 threshold: Option<f64>,
84 },
85 #[clap(about = "Create fixup commits for easier interactive rebasing")]
86 Fixup {
87 #[clap(help = "Commit hash to create fixup for")]
88 commit_hash: String,
89 #[clap(long = "rebase", help = "Automatically rebase with autosquash after creating fixup", action = clap::ArgAction::SetTrue)]
90 rebase: bool,
91 },
92 #[clap(about = "Advanced stash management with branch integration")]
93 StashBranch {
94 #[clap(subcommand)]
95 action: StashBranchAction,
96 },
97 #[clap(about = "Manage upstream branch relationships")]
98 Upstream {
99 #[clap(subcommand)]
100 action: UpstreamAction,
101 },
102 #[clap(about = "Interactive picker for recent branches")]
103 SwitchRecent,
104 #[clap(about = "Show contributor statistics for the repository")]
105 Contributors,
106 #[clap(about = "Analyze code complexity and technical debt metrics")]
107 TechnicalDebt,
108 #[clap(about = "Simplified bisect workflow")]
109 Bisect {
110 #[clap(subcommand)]
111 action: BisectAction,
112 },
113}
114
115#[derive(clap::Subcommand)]
116pub enum StashBranchAction {
117 #[clap(about = "Create a new branch from a stash")]
118 Create {
119 #[clap(help = "Name for the new branch")]
120 branch_name: String,
121 #[clap(long = "stash", help = "Stash reference (default: latest stash)")]
122 stash_ref: Option<String>,
123 },
124 #[clap(about = "Clean old stashes")]
125 Clean {
126 #[clap(
127 long = "older-than",
128 help = "Remove stashes older than (e.g., '7d', '2w', '1m')"
129 )]
130 older_than: Option<String>,
131 #[clap(long = "dry-run", help = "Show what would be cleaned without doing it", action = clap::ArgAction::SetTrue)]
132 dry_run: bool,
133 },
134 #[clap(about = "Apply stashes from a specific branch")]
135 ApplyByBranch {
136 #[clap(help = "Branch name to filter stashes by")]
137 branch_name: String,
138 #[clap(long = "list", help = "List stashes instead of applying", action = clap::ArgAction::SetTrue)]
139 list_only: bool,
140 },
141}
142
143#[derive(clap::Subcommand)]
144pub enum UpstreamAction {
145 #[clap(about = "Set upstream for current branch")]
146 Set {
147 #[clap(help = "Upstream branch reference (e.g., origin/main)")]
148 upstream: String,
149 },
150 #[clap(about = "Show upstream status for all branches")]
151 Status,
152 #[clap(about = "Sync all local branches with their upstreams")]
153 SyncAll {
154 #[clap(long = "dry-run", help = "Show what would be synced without doing it", action = clap::ArgAction::SetTrue
155 )]
156 dry_run: bool,
157 #[clap(long = "merge", help = "Use merge instead of rebase", action = clap::ArgAction::SetTrue
158 )]
159 merge: bool,
160 },
161}
162
163#[derive(clap::Subcommand)]
164pub enum BisectAction {
165 #[clap(about = "Start bisect session")]
166 Start {
167 #[clap(help = "Good commit reference")]
168 good: String,
169 #[clap(help = "Bad commit reference")]
170 bad: String,
171 },
172 #[clap(about = "Mark current commit as good")]
173 Good,
174 #[clap(about = "Mark current commit as bad")]
175 Bad,
176 #[clap(about = "Skip current commit (untestable)")]
177 Skip,
178 #[clap(about = "End bisect session")]
179 Reset,
180 #[clap(about = "Show bisect status")]
181 Status,
182}