diff --git a/CHANGELOG.md b/CHANGELOG.md index 197976e2d..c731e29b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj new` now always checks out the new commit (used to be only if the parent was `@`). +* (#330) `jj branch` now uses subcommands like `jj branch create` and + `jj branch forget` instead of options like `jj branch --forget`. + ### New features * `jj rebase` now accepts a `--branch/-b ` argument, which can be used diff --git a/src/commands.rs b/src/commands.rs index 8fa8d957c..1cc010e05 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -57,6 +57,7 @@ use jujutsu_lib::settings::UserSettings; use jujutsu_lib::store::Store; use jujutsu_lib::transaction::Transaction; use jujutsu_lib::tree::{merge_trees, Tree, TreeDiffIterator, TreeMergeError}; +use jujutsu_lib::view::View; use jujutsu_lib::working_copy::{ CheckoutStats, LockedWorkingCopy, ResetError, SnapshotError, WorkingCopy, }; @@ -1129,8 +1130,8 @@ enum Commands { Merge(MergeArgs), Rebase(RebaseArgs), Backout(BackoutArgs), - Branch(BranchArgs), - Branches(BranchesArgs), + #[clap(subcommand)] + Branch(BranchSubcommand), /// Undo an operation (shortcut for `jj op undo`) Undo(OperationUndoArgs), Operation(OperationArgs), @@ -1614,44 +1615,69 @@ struct BackoutArgs { destination: Vec, } -/// Create, update, or delete a branch +/// Manage branches. /// /// For information about branches, see /// https://github.com/martinvonz/jj/blob/main/docs/branches.md. -#[derive(clap::Args, Clone, Debug)] -struct BranchArgs { - /// The branch's target revision - #[clap(long, short, group = "action")] - revision: Option, +#[derive(clap::Subcommand, Clone, Debug)] +enum BranchSubcommand { + /// Create a new branch. + #[clap(visible_alias("c"))] + Create { + /// The branch's target revision. + #[clap(long, short)] + revision: Option, - /// Allow moving the branch backwards or sideways - #[clap(long, requires = "revision")] - allow_backwards: bool, + /// The branches to create. + #[clap(required = true)] + names: Vec, + }, - /// Delete the branch locally + /// Delete an existing branch and propagate the deletion to remotes on the + /// next push. + #[clap(visible_alias("d"))] + Delete { + /// The branches to delete. + #[clap(required = true)] + names: Vec, + }, + + /// Delete the local version of an existing branch, without propagating the + /// deletion to remotes. + #[clap(visible_alias("f"))] + Forget { + /// The branches to delete. + #[clap(required = true)] + names: Vec, + }, + + /// List branches and their targets /// - /// The deletion will be propagated to remotes on push. - #[clap(long, group = "action")] - delete: bool, + /// A remote branch will be included only if its target is different from + /// the local target. For a conflicted branch (both local and remote), old + /// target revisions are preceded by a "-" and new target revisions are + /// preceded by a "+". For information about branches, see + /// https://github.com/martinvonz/jj/blob/main/docs/branches.md. + #[clap(visible_alias("l"))] + List, - /// The name of the branch to move or delete - #[clap(long, group = "action")] - forget: bool, + /// Update a given branch to point to a certain commit. + #[clap(visible_alias("s"))] + Set { + /// The branch's target revision. + #[clap(long, short)] + revision: Option, - /// The branches to update. - names: Vec, + /// Allow moving the branch backwards or sideways. + #[clap(long)] + allow_backwards: bool, + + /// The branches to update. + #[clap(required = true)] + names: Vec, + }, } -/// List branches and their targets -/// -/// A remote branch will be included only if its target is different from the -/// local target. For a conflicted branch (both local and remote), old target -/// revisions are preceded by a "-" and new target revisions are preceded by a -/// "+". For information about branches, see -/// https://github.com/martinvonz/jj/blob/main/docs/branches.md. -#[derive(clap::Args, Clone, Debug)] -struct BranchesArgs {} - /// Commands for working with the operation log /// /// Commands for working with the operation log. For information about the @@ -4006,91 +4032,150 @@ fn is_fast_forward(repo: RepoRef, branch_name: &str, new_target_id: &CommitId) - } } -fn cmd_branch(ui: &mut Ui, command: &CommandHelper, args: &BranchArgs) -> Result<(), CommandError> { +fn cmd_branch( + ui: &mut Ui, + command: &CommandHelper, + subcommand: &BranchSubcommand, +) -> Result<(), CommandError> { let mut workspace_command = command.workspace_helper(ui)?; - let branch_names: Vec<&str> = if args.delete || args.forget { - let view = workspace_command.repo().view(); - args.names - .iter() - .map(|branch_name| match view.get_local_branch(branch_name) { - Some(_) => Ok(branch_name.as_str()), - None => Err(CommandError::UserError(format!( + let view = workspace_command.repo().view(); + fn validate_branch_names_exist<'a>( + view: &'a View, + names: &'a [String], + ) -> Result<(), CommandError> { + for branch_name in names { + if view.get_local_branch(branch_name).is_none() { + return Err(CommandError::UserError(format!( "No such branch: {}", branch_name - ))), - }) - .try_collect()? - } else { - args.names.iter().map(|name| name.as_str()).collect() - }; - - if branch_names.is_empty() { - ui.write_warn("warning: No branches provided.\n")?; + ))); + } + } + Ok(()) } - let branch_term = if branch_names.len() == 1 { - "branch" - } else { - "branches" - }; - let branch_term = format!("{branch_term} {}", branch_names.join(", ")); - if args.delete { - let mut tx = workspace_command.start_transaction(&format!("delete {branch_term}")); - for branch_name in branch_names { - tx.mut_repo().remove_local_branch(branch_name); - } - workspace_command.finish_transaction(ui, tx)?; - } else if args.forget { - let mut tx = workspace_command.start_transaction(&format!("forget {branch_term}")); - for branch_name in branch_names { - tx.mut_repo().remove_branch(branch_name); - } - workspace_command.finish_transaction(ui, tx)?; - } else { - if branch_names.len() > 1 { - ui.write_warn(format!( - "warning: Updating multiple branches ({}).\n", - branch_names.len() - ))?; - } - - let target_commit = - workspace_command.resolve_single_rev(ui, args.revision.as_deref().unwrap_or("@"))?; - if !args.allow_backwards - && !branch_names.iter().all(|branch_name| { - is_fast_forward( - workspace_command.repo().as_repo_ref(), - branch_name, - target_commit.id(), + fn make_branch_term(branch_names: &[impl AsRef]) -> String { + match branch_names { + [branch_name] => format!("branch {}", branch_name.as_ref()), + branch_names => { + format!( + "branches {}", + branch_names.iter().map(AsRef::as_ref).join(", ") ) - }) - { - return Err(CommandError::UserError( - "Use --allow-backwards to allow moving a branch backwards or sideways".to_string(), + } + } + } + + match subcommand { + BranchSubcommand::Create { revision, names } => { + let branch_names: Vec<&str> = names + .iter() + .map(|branch_name| match view.get_local_branch(branch_name) { + Some(_) => Err(CommandError::UserError(format!( + "Branch already exists: {} (use `jj branch set` to update it)", + branch_name + ))), + None => Ok(branch_name.as_str()), + }) + .try_collect()?; + + if branch_names.len() > 1 { + ui.write_warn(format!( + "warning: Creating multiple branches ({}).\n", + branch_names.len() + ))?; + } + + let target_commit = + workspace_command.resolve_single_rev(ui, revision.as_deref().unwrap_or("@"))?; + let mut tx = workspace_command.start_transaction(&format!( + "create {} pointing to commit {}", + make_branch_term(&branch_names), + target_commit.id().hex() )); + for branch_name in branch_names { + tx.mut_repo().set_local_branch( + branch_name.to_string(), + RefTarget::Normal(target_commit.id().clone()), + ); + } + workspace_command.finish_transaction(ui, tx)?; } - let mut tx = workspace_command.start_transaction(&format!( - "point {branch_term} to commit {}", - target_commit.id().hex() - )); - for branch_name in branch_names { - tx.mut_repo().set_local_branch( - branch_name.to_string(), - RefTarget::Normal(target_commit.id().clone()), - ); + + BranchSubcommand::Set { + revision, + allow_backwards, + names: branch_names, + } => { + if branch_names.len() > 1 { + ui.write_warn(format!( + "warning: Updating multiple branches ({}).\n", + branch_names.len() + ))?; + } + + let target_commit = + workspace_command.resolve_single_rev(ui, revision.as_deref().unwrap_or("@"))?; + if !allow_backwards + && !branch_names.iter().all(|branch_name| { + is_fast_forward( + workspace_command.repo().as_repo_ref(), + branch_name, + target_commit.id(), + ) + }) + { + return Err(CommandError::UserError( + "Use --allow-backwards to allow moving a branch backwards or sideways" + .to_string(), + )); + } + let mut tx = workspace_command.start_transaction(&format!( + "point {} to commit {}", + make_branch_term(branch_names), + target_commit.id().hex() + )); + for branch_name in branch_names { + tx.mut_repo().set_local_branch( + branch_name.to_string(), + RefTarget::Normal(target_commit.id().clone()), + ); + } + workspace_command.finish_transaction(ui, tx)?; + } + + BranchSubcommand::Delete { names } => { + validate_branch_names_exist(view, names)?; + let mut tx = + workspace_command.start_transaction(&format!("delete {}", make_branch_term(names))); + for branch_name in names { + tx.mut_repo().remove_local_branch(branch_name); + } + workspace_command.finish_transaction(ui, tx)?; + } + + BranchSubcommand::Forget { names } => { + validate_branch_names_exist(view, names)?; + let mut tx = + workspace_command.start_transaction(&format!("forget {}", make_branch_term(names))); + for branch_name in names { + tx.mut_repo().remove_branch(branch_name); + } + workspace_command.finish_transaction(ui, tx)?; + } + + BranchSubcommand::List => { + list_branches(ui, &workspace_command)?; } - workspace_command.finish_transaction(ui, tx)?; } Ok(()) } -fn cmd_branches( +fn list_branches( ui: &mut Ui, - command: &CommandHelper, - _args: &BranchesArgs, + workspace_command: &WorkspaceCommandHelper, ) -> Result<(), CommandError> { - let workspace_command = command.workspace_helper(ui)?; let repo = workspace_command.repo(); let workspace_id = workspace_command.workspace_id(); @@ -5153,7 +5238,6 @@ where Commands::Rebase(sub_args) => cmd_rebase(ui, &command_helper, sub_args), Commands::Backout(sub_args) => cmd_backout(ui, &command_helper, sub_args), Commands::Branch(sub_args) => cmd_branch(ui, &command_helper, sub_args), - Commands::Branches(sub_args) => cmd_branches(ui, &command_helper, sub_args), Commands::Undo(sub_args) => cmd_op_undo(ui, &command_helper, sub_args), Commands::Operation(sub_args) => cmd_operation(ui, &command_helper, sub_args), Commands::Workspace(sub_args) => cmd_workspace(ui, &command_helper, sub_args), diff --git a/tests/test_alias.rs b/tests/test_alias.rs index c34c058e3..fe5c92129 100644 --- a/tests/test_alias.rs +++ b/tests/test_alias.rs @@ -27,11 +27,11 @@ fn test_alias_basic() { b = ["log", "-r", "@", "-T", "branches"] "#, ); - test_env.jj_cmd_success(&repo_path, &["branch", "my-branch"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "my-branch"]); let stdout = test_env.jj_cmd_success(&repo_path, &["b"]); insta::assert_snapshot!(stdout, @r###" @ my-branch - ~ + ~ "###); } diff --git a/tests/test_branch_command.rs b/tests/test_branch_command.rs index 389159fbc..8da98ccba 100644 --- a/tests/test_branch_command.rs +++ b/tests/test_branch_command.rs @@ -35,7 +35,7 @@ fn test_branch_multiple_names() { let repo_path = test_env.env_root().join("repo"); let assert = test_env - .jj_cmd(&repo_path, &["branch", "foo", "bar"]) + .jj_cmd(&repo_path, &["branch", "set", "foo", "bar"]) .assert() .success(); insta::assert_snapshot!(get_stdout_string(&assert), @""); @@ -47,7 +47,7 @@ fn test_branch_multiple_names() { o 000000000000 "###); - let stdout = test_env.jj_cmd_success(&repo_path, &["branch", "--delete", "foo", "bar"]); + let stdout = test_env.jj_cmd_success(&repo_path, &["branch", "delete", "foo", "bar"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @ 230dd059e1b0 @@ -55,21 +55,6 @@ fn test_branch_multiple_names() { "###); } -#[test] -fn test_branch_hint_no_branches() { - let test_env = TestEnvironment::default(); - test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); - let repo_path = test_env.env_root().join("repo"); - - let assert = test_env - .jj_cmd(&repo_path, &["branch", "--delete"]) - .assert() - .success(); - let stderr = get_stderr_string(&assert); - insta::assert_snapshot!(stderr, @"warning: No branches provided. -"); -} - fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String { test_env.jj_cmd_success(cwd, &["log", "-T", r#"branches " " commit_id.short()"#]) } diff --git a/tests/test_edit_command.rs b/tests/test_edit_command.rs index 2e4d82e4e..d5a57df41 100644 --- a/tests/test_edit_command.rs +++ b/tests/test_edit_command.rs @@ -97,7 +97,7 @@ fn test_edit_merge() { std::fs::write(repo_path.join("file1"), "a\n").unwrap(); std::fs::write(repo_path.join("file2"), "a\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "b"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]); std::fs::write(repo_path.join("file1"), "b\n").unwrap(); std::fs::write(repo_path.join("file2"), "b\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["co", "@-"]); diff --git a/tests/test_git_colocated.rs b/tests/test_git_colocated.rs index ba57aa52b..06710efe5 100644 --- a/tests/test_git_colocated.rs +++ b/tests/test_git_colocated.rs @@ -51,7 +51,7 @@ fn test_git_colocated_rebase_on_import() { std::fs::write(workspace_root.join("file"), "contents").unwrap(); test_env.jj_cmd_success(&workspace_root, &["close", "-m", "add a file"]); std::fs::write(workspace_root.join("file"), "modified").unwrap(); - test_env.jj_cmd_success(&workspace_root, &["branch", "master"]); + test_env.jj_cmd_success(&workspace_root, &["branch", "set", "master"]); test_env.jj_cmd_success(&workspace_root, &["close", "-m", "modify a file"]); // TODO: We shouldn't need this command here to trigger an import of the // refs/heads/master we just exported diff --git a/tests/test_git_push.rs b/tests/test_git_push.rs index 7ac3cbd2f..e7b9b6abe 100644 --- a/tests/test_git_push.rs +++ b/tests/test_git_push.rs @@ -36,7 +36,7 @@ fn test_git_push() { // When pushing everything, won't push an open commit even if there's a branch // on it - test_env.jj_cmd_success(&workspace_root, &["branch", "my-branch"]); + test_env.jj_cmd_success(&workspace_root, &["branch", "create", "my-branch"]); let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @r###" Skipping branch 'my-branch' since it points to an open commit. @@ -63,7 +63,7 @@ fn test_git_push() { test_env.jj_cmd_success(&workspace_root, &["close", "-m", "second"]); std::fs::write(workspace_root.join("file"), "third").unwrap(); test_env.jj_cmd_success(&workspace_root, &["rebase", "-r", "@", "-d", "@--"]); - test_env.jj_cmd_success(&workspace_root, &["branch", "my-branch"]); + test_env.jj_cmd_success(&workspace_root, &["branch", "set", "my-branch"]); test_env.jj_cmd_success(&workspace_root, &["close", "-m", "third"]); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r###" diff --git a/tests/test_move_command.rs b/tests/test_move_command.rs index 528293279..bca282c3f 100644 --- a/tests/test_move_command.rs +++ b/tests/test_move_command.rs @@ -35,25 +35,25 @@ fn test_move() { // // When moving changes between e.g. C and F, we should not get unrelated changes // from B and D. - test_env.jj_cmd_success(&repo_path, &["branch", "a"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "a"]); std::fs::write(repo_path.join("file1"), "a\n").unwrap(); std::fs::write(repo_path.join("file2"), "a\n").unwrap(); std::fs::write(repo_path.join("file3"), "a\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "b"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]); std::fs::write(repo_path.join("file3"), "b\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "c"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "c"]); std::fs::write(repo_path.join("file1"), "c\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["co", "a"]); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "d"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "d"]); std::fs::write(repo_path.join("file3"), "d\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "e"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "e"]); std::fs::write(repo_path.join("file2"), "e\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "f"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "f"]); std::fs::write(repo_path.join("file2"), "f\n").unwrap(); // Test the setup insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -162,20 +162,20 @@ fn test_move_partial() { // D B // |/ // A - test_env.jj_cmd_success(&repo_path, &["branch", "a"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "a"]); std::fs::write(repo_path.join("file1"), "a\n").unwrap(); std::fs::write(repo_path.join("file2"), "a\n").unwrap(); std::fs::write(repo_path.join("file3"), "a\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "b"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]); std::fs::write(repo_path.join("file3"), "b\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "c"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "c"]); std::fs::write(repo_path.join("file1"), "c\n").unwrap(); std::fs::write(repo_path.join("file2"), "c\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["co", "a"]); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "d"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "d"]); std::fs::write(repo_path.join("file3"), "d\n").unwrap(); // Test the setup insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" diff --git a/tests/test_rebase_command.rs b/tests/test_rebase_command.rs index a5b999766..440d511ad 100644 --- a/tests/test_rebase_command.rs +++ b/tests/test_rebase_command.rs @@ -32,7 +32,7 @@ fn create_commit(test_env: &TestEnvironment, repo_path: &Path, name: &str, paren test_env.jj_cmd_success(repo_path, &["co", "@-"]); } std::fs::write(repo_path.join(name), &format!("{name}\n")).unwrap(); - test_env.jj_cmd_success(repo_path, &["branch", name]); + test_env.jj_cmd_success(repo_path, &["branch", "create", name]); test_env.jj_cmd_success(repo_path, &["close", "-m", name]); } diff --git a/tests/test_squash_command.rs b/tests/test_squash_command.rs index 9d01ed415..aa65df204 100644 --- a/tests/test_squash_command.rs +++ b/tests/test_squash_command.rs @@ -24,13 +24,13 @@ fn test_squash() { test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); let repo_path = test_env.env_root().join("repo"); - test_env.jj_cmd_success(&repo_path, &["branch", "a"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "a"]); std::fs::write(repo_path.join("file1"), "a\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "b"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]); std::fs::write(repo_path.join("file1"), "b\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "c"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "c"]); std::fs::write(repo_path.join("file1"), "c\n").unwrap(); // Test the setup insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -82,10 +82,10 @@ fn test_squash() { test_env.jj_cmd_success(&repo_path, &["undo"]); test_env.jj_cmd_success(&repo_path, &["co", "b"]); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "d"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "d"]); std::fs::write(repo_path.join("file2"), "d\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["merge", "-m", "merge", "c", "d"]); - test_env.jj_cmd_success(&repo_path, &["branch", "e", "-r", "@+"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "e", "-r", "@+"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" o b9ad3fdfc2c4 e |\ @@ -131,15 +131,15 @@ fn test_squash_partial() { test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); let repo_path = test_env.env_root().join("repo"); - test_env.jj_cmd_success(&repo_path, &["branch", "a"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "a"]); std::fs::write(repo_path.join("file1"), "a\n").unwrap(); std::fs::write(repo_path.join("file2"), "a\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "b"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]); std::fs::write(repo_path.join("file1"), "b\n").unwrap(); std::fs::write(repo_path.join("file2"), "b\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "c"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "c"]); std::fs::write(repo_path.join("file1"), "c\n").unwrap(); std::fs::write(repo_path.join("file2"), "c\n").unwrap(); // Test the setup diff --git a/tests/test_unsquash_command.rs b/tests/test_unsquash_command.rs index 6af87bb00..68cbd47af 100644 --- a/tests/test_unsquash_command.rs +++ b/tests/test_unsquash_command.rs @@ -24,13 +24,13 @@ fn test_unsquash() { test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); let repo_path = test_env.env_root().join("repo"); - test_env.jj_cmd_success(&repo_path, &["branch", "a"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "a"]); std::fs::write(repo_path.join("file1"), "a\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "b"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]); std::fs::write(repo_path.join("file1"), "b\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "c"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "c"]); std::fs::write(repo_path.join("file1"), "c\n").unwrap(); // Test the setup insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -81,10 +81,10 @@ fn test_unsquash() { test_env.jj_cmd_success(&repo_path, &["undo"]); test_env.jj_cmd_success(&repo_path, &["co", "b"]); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "d"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "d"]); std::fs::write(repo_path.join("file2"), "d\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["merge", "-m", "merge", "c", "d"]); - test_env.jj_cmd_success(&repo_path, &["branch", "e", "-r", "@+"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "e", "-r", "@+"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" o b9ad3fdfc2c4 e |\ @@ -129,15 +129,15 @@ fn test_unsquash_partial() { test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); let repo_path = test_env.env_root().join("repo"); - test_env.jj_cmd_success(&repo_path, &["branch", "a"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "a"]); std::fs::write(repo_path.join("file1"), "a\n").unwrap(); std::fs::write(repo_path.join("file2"), "a\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "b"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]); std::fs::write(repo_path.join("file1"), "b\n").unwrap(); std::fs::write(repo_path.join("file2"), "b\n").unwrap(); test_env.jj_cmd_success(&repo_path, &["new"]); - test_env.jj_cmd_success(&repo_path, &["branch", "c"]); + test_env.jj_cmd_success(&repo_path, &["branch", "create", "c"]); std::fs::write(repo_path.join("file1"), "c\n").unwrap(); std::fs::write(repo_path.join("file2"), "c\n").unwrap(); // Test the setup