From c86c194aad96a4665ada5b3ad2816887de885987 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Fri, 21 Jun 2024 18:00:04 +0900 Subject: [PATCH] cli: branch: make "set" do upsert as before Since "set " often adds a if not exists, it make some sense that "branch set" does upsert. The current "branch set" use case is now covered by "branch move", so it's okay to change the "set" behavior. If new branch is created by "branch set", status message and hint will be printed to help migration. The user should be able to undo creation if it was a mistake. Closes #3584 --- CHANGELOG.md | 4 ++++ cli/src/commands/branch/set.rs | 21 ++++++++++++++++----- cli/tests/cli-reference@.md.snap | 4 ++-- cli/tests/test_branch_command.rs | 12 +++++------- 4 files changed, 27 insertions(+), 14 deletions(-) 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"]);