From 3c80e3453db6f6be03f7195ef4c2465afbf5daa6 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 134613f38..fa54822c7 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 06b8e0476..3757fc810 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 3c485485a..50e35bd13 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 d21425e2a..560f31c51 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"]);