diff --git a/CHANGELOG.md b/CHANGELOG.md index 134613f38b..fa54822c71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Dropped support for deprecated `jj branch delete`/`forget` `--glob` option. +* `jj branch set` now creates new branch if it doesn't exist. Use `jj branch + move` to ensure that the target branch already exists. + [#3584](https://github.com/martinvonz/jj/issues/3584) + ### Deprecations * Replacing `-l` shorthand for `--limit` with `-n` in `jj log`, `jj op log` and `jj obslog`. diff --git a/cli/src/commands/branch/set.rs b/cli/src/commands/branch/set.rs index 06b8e0476c..3757fc8106 100644 --- a/cli/src/commands/branch/set.rs +++ b/cli/src/commands/branch/set.rs @@ -21,7 +21,7 @@ use crate::cli_util::{CommandHelper, RevisionArg}; use crate::command_error::{user_error_with_hint, CommandError}; use crate::ui::Ui; -/// Update an existing branch to point to a certain commit +/// Create or update a branch to point to a certain commit #[derive(clap::Args, Clone, Debug)] pub struct BranchSetArgs { /// The branch's target revision @@ -47,13 +47,11 @@ pub fn cmd_branch_set( workspace_command.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?; let repo = workspace_command.repo().as_ref(); let branch_names = &args.names; + let mut new_branch_names: Vec<&str> = Vec::new(); for name in branch_names { let old_target = repo.view().get_local_branch(name); if old_target.is_absent() { - return Err(user_error_with_hint( - format!("No such branch: {name}"), - "Use `jj branch create` to create it.", - )); + new_branch_names.push(name); } if !args.allow_backwards && !is_fast_forward(repo, old_target, target_commit.id()) { return Err(user_error_with_hint( @@ -84,5 +82,18 @@ pub fn cmd_branch_set( target_commit.id().hex() ), )?; + + if !new_branch_names.is_empty() { + writeln!( + ui.status(), + "Created branches: {}", + new_branch_names.join(", "), + )?; + // TODO: delete this hint in jj 0.25+ + writeln!( + ui.hint_default(), + "Consider using `jj branch move` if your intention was to move existing branches." + )?; + } Ok(()) } diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index b610e63b03..fe734225c5 100644 --- a/cli/tests/cli-reference@.md.snap +++ b/cli/tests/cli-reference@.md.snap @@ -239,7 +239,7 @@ For information about branches, see https://github.com/martinvonz/jj/blob/main/d * `list` — List branches and their targets * `move` — Move existing branches to target revision * `rename` — Rename `old` branch name to `new` branch name -* `set` — Update an existing branch to point to a certain commit +* `set` — Create or update a branch to point to a certain commit * `track` — Start tracking given remote branches * `untrack` — Stop tracking given remote branches @@ -370,7 +370,7 @@ The new branch name points at the same commit as the old branch name. ## `jj branch set` -Update an existing branch to point to a certain commit +Create or update a branch to point to a certain commit **Usage:** `jj branch set [OPTIONS] ...` diff --git a/cli/tests/test_branch_command.rs b/cli/tests/test_branch_command.rs index d21425e2a0..560f31c51c 100644 --- a/cli/tests/test_branch_command.rs +++ b/cli/tests/test_branch_command.rs @@ -103,18 +103,16 @@ fn test_branch_move() { test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); let repo_path = test_env.env_root().join("repo"); - let stderr = test_env.jj_cmd_failure(&repo_path, &["branch", "set", "foo"]); - insta::assert_snapshot!(stderr, @r###" - Error: No such branch: foo - Hint: Use `jj branch create` to create it. - "###); let stderr = test_env.jj_cmd_failure(&repo_path, &["branch", "move", "foo"]); insta::assert_snapshot!(stderr, @r###" Error: No such branch: foo "###); - let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["branch", "create", "foo"]); - insta::assert_snapshot!(stderr, @""); + let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["branch", "set", "foo"]); + insta::assert_snapshot!(stderr, @r###" + Created branches: foo + Hint: Consider using `jj branch move` if your intention was to move existing branches. + "###); test_env.jj_cmd_ok(&repo_path, &["new"]); let stderr = test_env.jj_cmd_failure(&repo_path, &["branch", "create", "foo"]);