Skip to main content

git_stk/commands/
rename.rs

1use anyhow::Result;
2use clap_complete::engine::ArgValueCompleter;
3
4use crate::commands::Run;
5use crate::completions;
6use crate::providers::{detect_provider, review_provider};
7use crate::{git, stack};
8
9/// Rename a branch and retarget its stack children.
10#[derive(Debug, clap::Args)]
11pub struct Rename {
12    /// New name for the current branch, or a branch and its new name.
13    #[arg(
14        required = true,
15        num_args = 1..=2,
16        value_name = "[BRANCH] NEW_NAME",
17        add = ArgValueCompleter::new(completions::branch_candidates),
18    )]
19    names: Vec<String>,
20}
21
22impl Run for Rename {
23    fn run(self) -> Result<()> {
24        let (old, new) = match self.names.as_slice() {
25            [new] => (git::current_branch()?, new.clone()),
26            [old, new] => (old.clone(), new.clone()),
27            _ => unreachable!("clap enforces one or two names"),
28        };
29        rename(&old, &new)
30    }
31}
32
33fn rename(old: &str, new: &str) -> Result<()> {
34    stack::rename_branch(old, new)?;
35
36    // Best effort: an existing review still heads the old branch name, and
37    // the platform does not follow local renames.
38    if let Ok(provider) = detect_provider() {
39        let review_provider = review_provider(provider.kind);
40        if let Ok(Some(review)) = review_provider.review_for_branch(old)
41            && review.branch == *old
42        {
43            println!(
44                "warning: review {} still heads {old}; submitting {new} will open a new review",
45                review.id
46            );
47        }
48    }
49
50    Ok(())
51}