|
1 | 1 | use but_settings::AppSettings; |
2 | | -use but_workspace::StackId; |
| 2 | +use but_workspace::{StackId, ui::StackEntry}; |
3 | 3 | use gitbutler_command_context::CommandContext; |
4 | 4 | use gitbutler_project::Project; |
5 | 5 | use std::io::{self, Write}; |
@@ -37,6 +37,14 @@ pub enum Subcommands { |
37 | 37 | #[clap(long, short = 'l')] |
38 | 38 | local: bool, |
39 | 39 | }, |
| 40 | + /// Unapply a branch from the workspace |
| 41 | + Unapply { |
| 42 | + /// Name of the branch to unapply |
| 43 | + branch_name: String, |
| 44 | + /// Force unapply without confirmation |
| 45 | + #[clap(long, short = 'f')] |
| 46 | + force: bool, |
| 47 | + }, |
40 | 48 | } |
41 | 49 |
|
42 | 50 | pub fn handle(cmd: &Subcommands, project: &Project, _json: bool) -> anyhow::Result<()> { |
@@ -133,9 +141,68 @@ pub fn handle(cmd: &Subcommands, project: &Project, _json: bool) -> anyhow::Resu |
133 | 141 | Ok(()) |
134 | 142 | } |
135 | 143 | Subcommands::List { local } => list::list(project, *local), |
| 144 | + Subcommands::Unapply { branch_name, force } => { |
| 145 | + let stacks = but_api::workspace::stacks( |
| 146 | + project.id, |
| 147 | + Some(but_workspace::StacksFilter::InWorkspace), |
| 148 | + )?; |
| 149 | + |
| 150 | + // Find which stack this branch belongs to |
| 151 | + for stack_entry in &stacks { |
| 152 | + if stack_entry.heads.iter().all(|b| b.name != *branch_name) { |
| 153 | + // Not found in this stack, |
| 154 | + continue; |
| 155 | + } |
| 156 | + |
| 157 | + if let Some(sid) = stack_entry.id { |
| 158 | + return confirm_unapply_stack(project, sid, stack_entry, force); |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + println!("Branch '{}' not found in any stack", branch_name); |
| 163 | + Ok(()) |
| 164 | + } |
136 | 165 | } |
137 | 166 | } |
138 | 167 |
|
| 168 | +fn confirm_unapply_stack( |
| 169 | + project: &Project, |
| 170 | + sid: StackId, |
| 171 | + stack_entry: &StackEntry, |
| 172 | + force: &bool, |
| 173 | +) -> Result<(), anyhow::Error> { |
| 174 | + let branches = stack_entry |
| 175 | + .heads |
| 176 | + .iter() |
| 177 | + .map(|head| head.name.to_string()) |
| 178 | + .collect::<Vec<_>>() |
| 179 | + .join(", "); |
| 180 | + |
| 181 | + if !force { |
| 182 | + println!( |
| 183 | + "Are you sure you want to unapply stack with branches '{}'? [y/N]:", |
| 184 | + branches |
| 185 | + ); |
| 186 | + |
| 187 | + io::stdout().flush()?; |
| 188 | + let mut input = String::new(); |
| 189 | + io::stdin().read_line(&mut input)?; |
| 190 | + |
| 191 | + let input = input.trim().to_lowercase(); |
| 192 | + if input != "y" && input != "yes" { |
| 193 | + println!("Aborted unapply operation."); |
| 194 | + return Ok(()); |
| 195 | + } |
| 196 | + } |
| 197 | + |
| 198 | + but_api::virtual_branches::unapply_stack(project.id, sid)?; |
| 199 | + println!( |
| 200 | + "Unapplied stack with branches '{}' from workspace", |
| 201 | + branches |
| 202 | + ); |
| 203 | + Ok(()) |
| 204 | +} |
| 205 | + |
139 | 206 | fn confirm_branch_deletion( |
140 | 207 | project: &Project, |
141 | 208 | sid: StackId, |
|
0 commit comments