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