From bf2076622c5df2fa7db10b40afac658591149533 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Wed, 19 Jun 2024 20:18:14 +0900 Subject: [PATCH] cli: branch: add "set --allow-new" flag Since "set " often adds a as needed, it make some sense that "branch set" does upsert. The added flag helps re-execute a failed "set" command to create new branch. I'm hoping to make it the default by migrating existing "branch set" users to "branch move", but changing the default behavior right now can cause problems. So, let's add an opt-in flag first. Closes #3584 --- CHANGELOG.md | 4 ++++ cli/src/commands/branch/set.rs | 12 ++++++++---- cli/tests/cli-reference@.md.snap | 5 +++-- cli/tests/test_branch_command.rs | 13 ++++++++++--- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c0739ff7ac..3d7a65f863e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * New command `jj branch move` let you update branches by name pattern or source revision. +* `jj branch set` now accepts `--allow-new` option to create new branch if it + doesn't exist. + [#3584](https://github.com/martinvonz/jj/issues/3584) + * New diff option `jj diff --name-only` allows for easier shell scripting. ### Fixed bugs diff --git a/cli/src/commands/branch/set.rs b/cli/src/commands/branch/set.rs index 06b8e0476c8..184bcca82c7 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 +/// Update a branch to point to a certain commit #[derive(clap::Args, Clone, Debug)] pub struct BranchSetArgs { /// The branch's target revision @@ -32,6 +32,10 @@ pub struct BranchSetArgs { #[arg(long, short = 'B')] allow_backwards: bool, + /// Allow creating new branch + #[arg(long, short = 'N')] + allow_new: bool, + /// The branches to update #[arg(required = true, value_parser = NonEmptyStringValueParser::new())] names: Vec, @@ -49,10 +53,10 @@ pub fn cmd_branch_set( let branch_names = &args.names; for name in branch_names { let old_target = repo.view().get_local_branch(name); - if old_target.is_absent() { + if !args.allow_new && old_target.is_absent() { return Err(user_error_with_hint( - format!("No such branch: {name}"), - "Use `jj branch create` to create it.", + format!("Refusing to create new branch: {name}"), + "Use --allow-new to create it.", )); } if !args.allow_backwards && !is_fast_forward(repo, old_target, target_commit.id()) { diff --git a/cli/tests/cli-reference@.md.snap b/cli/tests/cli-reference@.md.snap index 0ca166a0244..01b61cf8a1a 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` — 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 +Update a branch to point to a certain commit **Usage:** `jj branch set [OPTIONS] ...` @@ -382,6 +382,7 @@ Update an existing branch to point to a certain commit * `-r`, `--revision ` — The branch's target revision * `-B`, `--allow-backwards` — Allow moving the branch backwards or sideways +* `-N`, `--allow-new` — Allow creating new branch diff --git a/cli/tests/test_branch_command.rs b/cli/tests/test_branch_command.rs index c706e62485a..f408ff390b6 100644 --- a/cli/tests/test_branch_command.rs +++ b/cli/tests/test_branch_command.rs @@ -105,16 +105,23 @@ fn test_branch_move() { 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. + Error: Refusing to create new branch: foo + Hint: Use --allow-new 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"]); + // "set --allow-new" should work no matter if branch exists + let (_stdout, stderr) = + test_env.jj_cmd_ok(&repo_path, &["branch", "set", "--allow-new", "foo"]); insta::assert_snapshot!(stderr, @""); + let (_stdout, stderr) = + test_env.jj_cmd_ok(&repo_path, &["branch", "set", "--allow-new", "foo"]); + insta::assert_snapshot!(stderr, @r###" + Nothing changed. + "###); test_env.jj_cmd_ok(&repo_path, &["new"]); let stderr = test_env.jj_cmd_failure(&repo_path, &["branch", "create", "foo"]);