Skip to content

Commit

Permalink
Implement a rename subcommand for the branch command.
Browse files Browse the repository at this point in the history
This is really a simple change that does the following in a transaction:
* Set the new branch name to point to the same commit as the old branch name.
* Set the old branch name to point to no commit (hence deleting the old name).

Before it starts, it confirms that the new branch name is not already in use.
  • Loading branch information
essiene committed Dec 16, 2023
1 parent d39843b commit fd2f38c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### New features

* Information about new and resolved conflicts is now printed by every command.
* `jj branch` has gained a new `rename` subcommand that allows changing a branch
name atomically. `jj branch help rename` for details.

### Fixed bugs

Expand Down
51 changes: 51 additions & 0 deletions cli/src/commands/branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ pub enum BranchSubcommand {
Forget(BranchForgetArgs),
#[command(visible_alias("l"))]
List(BranchListArgs),
#[command(visible_alias("r"))]
Rename(BranchRenameArgs),
#[command(visible_alias("s"))]
Set(BranchSetArgs),
Track(BranchTrackArgs),
Expand Down Expand Up @@ -122,6 +124,19 @@ pub struct BranchForgetArgs {
pub glob: Vec<StringPattern>,
}

/// Rename `old` branch name to `new` branch name.
///
/// The new branch name points at the same commit as the old
/// branch name.
#[derive(clap::Args, Clone, Debug)]
pub struct BranchRenameArgs {
/// The old name of the branch.
pub old: String,

/// The new name of the branch.
pub new: String,
}

/// Update an existing branch to point to a certain commit.
#[derive(clap::Args, Clone, Debug)]
pub struct BranchSetArgs {
Expand Down Expand Up @@ -248,6 +263,7 @@ pub fn cmd_branch(
) -> Result<(), CommandError> {
match subcommand {
BranchSubcommand::Create(sub_args) => cmd_branch_create(ui, command, sub_args),
BranchSubcommand::Rename(sub_args) => cmd_branch_rename(ui, command, sub_args),
BranchSubcommand::Set(sub_args) => cmd_branch_set(ui, command, sub_args),
BranchSubcommand::Delete(sub_args) => cmd_branch_delete(ui, command, sub_args),
BranchSubcommand::Forget(sub_args) => cmd_branch_forget(ui, command, sub_args),
Expand Down Expand Up @@ -301,6 +317,41 @@ fn cmd_branch_create(
Ok(())
}

fn cmd_branch_rename(
ui: &mut Ui,
command: &CommandHelper,
args: &BranchRenameArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let repo = workspace_command.repo().as_ref();
let old_branch = &args.old;
// call clone because .set_local_branch_target takes ownership
// of the target_commit, so we need to create a copy that is no
// longer owned by the workspace.
let target_commit = repo.view().get_local_branch(old_branch).clone();
if target_commit.is_absent() {
return Err(user_error_with_hint(format!(
"No such branch: {old_branch}"
)));
}

let new_branch = &args.new;
let mut tx = workspace_command.start_transaction();
tx.mut_repo()
.set_local_branch_target(new_branch, target_commit);
tx.mut_repo()
.set_local_branch_target(old_branch, RefTarget::absent());
tx.finish(
ui,
format!(
"rename {} to {}",
make_branch_term(&[old_branch]),
make_branch_term(&[new_branch]),
),
)?;
Ok(())
}

fn cmd_branch_set(
ui: &mut Ui,
command: &CommandHelper,
Expand Down

0 comments on commit fd2f38c

Please sign in to comment.