Skip to main content

mkit_cli/commands/
switch.rs

1//! `mkit switch` — git's modern branch-switch UX, a thin front-end over
2//! `mkit checkout`. `switch <branch>` switches to an existing branch;
3//! `switch -c <new> [<start>]` creates a branch and switches to it;
4//! `switch -C <new> [<start>]` creates-or-resets it. All the safety
5//! guards and output strings come from `checkout` unchanged.
6
7use clap::Parser;
8
9use crate::clap_shim;
10
11#[derive(Debug, Parser)]
12#[command(name = "mkit switch", about = "Switch branches (git switch).")]
13struct SwitchOpts {
14    /// Create a new branch and switch to it (`git switch -c`).
15    #[arg(short = 'c', value_name = "NEW", conflicts_with = "create_force")]
16    create: Option<String>,
17    /// Create-or-reset a branch and switch to it (`git switch -C`).
18    #[arg(short = 'C', value_name = "NEW")]
19    create_force: Option<String>,
20    /// Branch to switch to, or the start-point when used with `-c`/`-C`.
21    target: Option<String>,
22}
23
24#[must_use]
25pub fn run(args: &[String]) -> u8 {
26    let opts = match clap_shim::parse::<SwitchOpts>("mkit switch", args) {
27        Ok(o) => o,
28        Err(code) => return code,
29    };
30    let has_create = opts.create.is_some() || opts.create_force.is_some();
31    // Translate to checkout's argument surface and delegate (checkout owns
32    // the clobber guard + the `Switched to …` reporting).
33    let mut fwd: Vec<String> = Vec::new();
34    if let Some(new) = opts.create.as_deref() {
35        fwd.push("-b".to_owned());
36        fwd.push(new.to_owned());
37    } else if let Some(new) = opts.create_force.as_deref() {
38        fwd.push("-B".to_owned());
39        fwd.push(new.to_owned());
40    }
41    match opts.target.as_deref() {
42        Some(t) => fwd.push(t.to_owned()),
43        None if !has_create => {
44            return super::usage_error("usage: mkit switch [-c|-C <new>] <branch>");
45        }
46        None => {}
47    }
48    super::checkout::run(&fwd)
49}