diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ec90d38bd..d5ced5c4de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ### Breaking changes +* `jj move` has been removed. It was deprecated in 0.16.0. + ### Deprecations ### New features diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index 6efdfeb646..064ddb4aec 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -36,7 +36,6 @@ mod init; mod interdiff; mod log; mod merge; -mod r#move; mod new; mod next; mod operation; @@ -133,8 +132,6 @@ enum Command { /// arguments. #[command(hide = true)] Merge(new::NewArgs), - #[command(hide = true)] - Move(r#move::MoveArgs), New(new::NewArgs), Next(next::NextArgs), #[command(subcommand)] @@ -232,7 +229,6 @@ pub fn run_command(ui: &mut Ui, command_helper: &CommandHelper) -> Result<(), Co Command::Interdiff(args) => interdiff::cmd_interdiff(ui, command_helper, args), Command::Log(args) => log::cmd_log(ui, command_helper, args), Command::Merge(args) => merge::cmd_merge(ui, command_helper, args), - Command::Move(args) => r#move::cmd_move(ui, command_helper, args), Command::New(args) => new::cmd_new(ui, command_helper, args), Command::Next(args) => next::cmd_next(ui, command_helper, args), Command::Evolog(args) => evolog::cmd_evolog(ui, command_helper, args), diff --git a/cli/src/commands/move.rs b/cli/src/commands/move.rs deleted file mode 100644 index 236dc09e11..0000000000 --- a/cli/src/commands/move.rs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2020 The Jujutsu Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use clap::ArgGroup; -use clap_complete::ArgValueCandidates; -use jj_lib::object_id::ObjectId; -use tracing::instrument; - -use super::squash::move_diff; -use super::squash::SquashedDescription; -use crate::cli_util::CommandHelper; -use crate::cli_util::RevisionArg; -use crate::command_error::user_error; -use crate::command_error::CommandError; -use crate::complete; -use crate::ui::Ui; - -/// Move changes from one revision into another (DEPRECATED, use `jj squash`) -/// -/// Use `--interactive` to move only part of the source revision into the -/// destination. The selected changes (or all the changes in the source revision -/// if not using `--interactive`) will be moved into the destination. The -/// changes will be removed from the source. If that means that the source is -/// now empty compared to its parent, it will be abandoned. Without -/// `--interactive`, the source change will always be empty. -/// -/// If the source became empty and both the source and destination had a -/// non-empty description, you will be asked for the combined description. If -/// either was empty, then the other one will be used. -/// -/// If a working-copy commit gets abandoned, it will be given a new, empty -/// commit. This is true in general; it is not specific to this command. -#[derive(clap::Args, Clone, Debug)] -#[command(group(ArgGroup::new("to_move").args(&["from", "to"]).multiple(true).required(true)))] -pub(crate) struct MoveArgs { - /// Move part of this change into the destination - #[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))] - from: Option, - /// Move part of the source into this change - #[arg(long, short, add = ArgValueCandidates::new(complete::mutable_revisions))] - to: Option, - /// Interactively choose which parts to move - #[arg(long, short)] - interactive: bool, - /// Specify diff editor to be used (implies --interactive) - #[arg(long, value_name = "NAME")] - tool: Option, - /// Move only changes to these paths (instead of all paths) - #[arg(conflicts_with_all = ["interactive", "tool"], value_hint = clap::ValueHint::AnyPath)] - paths: Vec, -} - -#[instrument(skip_all)] -pub(crate) fn cmd_move( - ui: &mut Ui, - command: &CommandHelper, - args: &MoveArgs, -) -> Result<(), CommandError> { - writeln!( - ui.warning_default(), - "`jj move` is deprecated; use `jj squash` instead, which is equivalent" - )?; - writeln!( - ui.warning_default(), - "`jj move` will be removed in a future version, and this will be a hard error" - )?; - let mut workspace_command = command.workspace_helper(ui)?; - let source = - workspace_command.resolve_single_rev(ui, args.from.as_ref().unwrap_or(&RevisionArg::AT))?; - let destination = - workspace_command.resolve_single_rev(ui, args.to.as_ref().unwrap_or(&RevisionArg::AT))?; - if source.id() == destination.id() { - return Err(user_error("Source and destination cannot be the same.")); - } - let matcher = workspace_command - .parse_file_patterns(ui, &args.paths)? - .to_matcher(); - let diff_selector = - workspace_command.diff_selector(ui, args.tool.as_deref(), args.interactive)?; - let mut tx = workspace_command.start_transaction(); - let tx_description = format!( - "move changes from {} to {}", - source.id().hex(), - destination.id().hex() - ); - move_diff( - ui, - &mut tx, - command.settings(), - &[source], - &destination, - matcher.as_ref(), - &diff_selector, - SquashedDescription::Combine, - false, - &args.paths, - false, - )?; - tx.finish(ui, tx_description)?; - Ok(()) -} diff --git a/cli/src/commands/squash.rs b/cli/src/commands/squash.rs index 5baeb6dcbd..a32c353f5e 100644 --- a/cli/src/commands/squash.rs +++ b/cli/src/commands/squash.rs @@ -162,8 +162,7 @@ pub(crate) fn cmd_squash( Ok(()) } -// TODO(#2882): Remove public visibility once `jj move` is deleted. -pub(crate) enum SquashedDescription { +enum SquashedDescription { // Use this exact description. Exact(String), // Use the destination's description and discard the descriptions of the @@ -173,9 +172,8 @@ pub(crate) enum SquashedDescription { Combine, } -// TODO(#2882): Remove public visibility once `jj move` is deleted. impl SquashedDescription { - pub(crate) fn from_args(args: &SquashArgs) -> Self { + fn from_args(args: &SquashArgs) -> Self { // These options are incompatible and Clap is configured to prevent this. assert!(args.message_paragraphs.is_empty() || !args.use_destination_message); @@ -191,7 +189,7 @@ impl SquashedDescription { } #[allow(clippy::too_many_arguments)] -pub fn move_diff( +fn move_diff( ui: &mut Ui, tx: &mut WorkspaceCommandTransaction, settings: &UserSettings, diff --git a/cli/tests/runner.rs b/cli/tests/runner.rs index d5c332bfd3..e95b89fac3 100644 --- a/cli/tests/runner.rs +++ b/cli/tests/runner.rs @@ -52,7 +52,6 @@ mod test_immutable_commits; mod test_init_command; mod test_interdiff_command; mod test_log_command; -mod test_move_command; mod test_new_command; mod test_next_prev_commands; mod test_operations; diff --git a/cli/tests/test_immutable_commits.rs b/cli/tests/test_immutable_commits.rs index e13a98b6fd..310b285e33 100644 --- a/cli/tests/test_immutable_commits.rs +++ b/cli/tests/test_immutable_commits.rs @@ -247,24 +247,6 @@ fn test_rewrite_immutable_commands() { Hint: Could not modify commit: mzvwutvl 1d5af877 main | (conflict) merge Hint: Pass `--ignore-immutable` or configure the set of immutable commits via `revset-aliases.immutable_heads()`. "#); - // move --from - let stderr = test_env.jj_cmd_failure(&repo_path, &["move", "--from=main"]); - insta::assert_snapshot!(stderr, @r#" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Error: Commit 1d5af877b8bb is immutable - Hint: Could not modify commit: mzvwutvl 1d5af877 main | (conflict) merge - Hint: Pass `--ignore-immutable` or configure the set of immutable commits via `revset-aliases.immutable_heads()`. - "#); - // move --to - let stderr = test_env.jj_cmd_failure(&repo_path, &["move", "--to=main"]); - insta::assert_snapshot!(stderr, @r#" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Error: Commit 1d5af877b8bb is immutable - Hint: Could not modify commit: mzvwutvl 1d5af877 main | (conflict) merge - Hint: Pass `--ignore-immutable` or configure the set of immutable commits via `revset-aliases.immutable_heads()`. - "#); // new --insert-before let stderr = test_env.jj_cmd_failure(&repo_path, &["new", "--insert-before", "main"]); insta::assert_snapshot!(stderr, @r#" diff --git a/cli/tests/test_move_command.rs b/cli/tests/test_move_command.rs deleted file mode 100644 index 763925b4ab..0000000000 --- a/cli/tests/test_move_command.rs +++ /dev/null @@ -1,467 +0,0 @@ -// Copyright 2022 The Jujutsu Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::path::Path; -use std::path::PathBuf; - -use crate::common::TestEnvironment; - -#[test] -fn test_move() { - let test_env = TestEnvironment::default(); - test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); - let repo_path = test_env.env_root().join("repo"); - - // Create history like this: - // F - // | - // E C - // | | - // D B - // |/ - // A - // - // When moving changes between e.g. C and F, we should not get unrelated changes - // from B and D. - test_env.jj_cmd_ok(&repo_path, &["bookmark", "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_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "create", "b"]); - std::fs::write(repo_path.join("file3"), "b\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "create", "c"]); - std::fs::write(repo_path.join("file1"), "c\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["edit", "a"]); - test_env.jj_cmd_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "create", "d"]); - std::fs::write(repo_path.join("file3"), "d\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "create", "e"]); - std::fs::write(repo_path.join("file2"), "e\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "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###" - @ a847ab4967fe f - ○ c2f9de87325d e - ○ e0dac715116f d - │ ○ 59597b34a0d8 c - │ ○ 12d6103dc0c8 b - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - - // Errors out without arguments - let stderr = test_env.jj_cmd_cli_error(&repo_path, &["move"]); - insta::assert_snapshot!(stderr, @r###" - error: the following required arguments were not provided: - <--from |--to > - - Usage: jj move <--from |--to > [PATHS]... - - For more information, try '--help'. - "###); - // Errors out if source and destination are the same - let stderr = test_env.jj_cmd_failure(&repo_path, &["move", "--to", "@"]); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Error: Source and destination cannot be the same. - "###); - - // Can move from sibling, which results in the source being abandoned - let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["move", "--from", "c"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Working copy now at: kmkuslsw a45950b1 f | (no description set) - Parent commit : znkkpsqq c2f9de87 e | (no description set) - Added 0 files, modified 1 files, removed 0 files - "###); - insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ a45950b1b7ff f - ○ c2f9de87325d e - ○ e0dac715116f d - │ ○ 12d6103dc0c8 b c - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - // The change from the source has been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); - insta::assert_snapshot!(stdout, @r###" - c - "###); - // File `file2`, which was not changed in source, is unchanged - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2"]); - insta::assert_snapshot!(stdout, @r###" - f - "###); - - // Can move from ancestor - test_env.jj_cmd_ok(&repo_path, &["undo"]); - let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["move", "--from", "@--"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Working copy now at: kmkuslsw 5e5727af f | (no description set) - Parent commit : znkkpsqq ed9c4164 e | (no description set) - "###); - // The change has been removed from the source (the change pointed to by 'd' - // became empty and was abandoned) - insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 5e5727af3d75 f - ○ ed9c41643a77 e - │ ○ 59597b34a0d8 c - │ ○ 12d6103dc0c8 b - ├─╯ - ○ b7b767179c44 a d - ◆ 000000000000 - "###); - // The change from the source has been applied (the file contents were already - // "f", as is typically the case when moving changes from an ancestor) - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2"]); - insta::assert_snapshot!(stdout, @r###" - f - "###); - - // Can move from descendant - test_env.jj_cmd_ok(&repo_path, &["undo"]); - let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["move", "--from", "e", "--to", "d"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Rebased 1 descendant commits - Working copy now at: kmkuslsw e21f6bb0 f | (no description set) - Parent commit : vruxwmqv 3cf0fa77 d e | (no description set) - "###); - // The change has been removed from the source (the change pointed to by 'e' - // became empty and was abandoned) - insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ e21f6bb01bae f - ○ 3cf0fa772663 d e - │ ○ 59597b34a0d8 c - │ ○ 12d6103dc0c8 b - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - // The change from the source has been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2", "-r", "d"]); - insta::assert_snapshot!(stdout, @r###" - e - "###); -} - -#[test] -fn test_move_partial() { - let mut test_env = TestEnvironment::default(); - test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); - let repo_path = test_env.env_root().join("repo"); - - // Create history like this: - // C - // | - // D B - // |/ - // A - test_env.jj_cmd_ok(&repo_path, &["bookmark", "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_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "create", "b"]); - std::fs::write(repo_path.join("file3"), "b\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "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_ok(&repo_path, &["edit", "a"]); - test_env.jj_cmd_ok(&repo_path, &["new"]); - test_env.jj_cmd_ok(&repo_path, &["bookmark", "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###" - @ e0dac715116f d - │ ○ 087591be5a01 c - │ ○ 12d6103dc0c8 b - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - - let edit_script = test_env.set_up_fake_diff_editor(); - - // If we don't make any changes in the diff-editor, the whole change is moved - let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["move", "-i", "--from", "c"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Working copy now at: vruxwmqv 987bcfb2 d | (no description set) - Parent commit : qpvuntsm b7b76717 a | (no description set) - Added 0 files, modified 2 files, removed 0 files - "###); - insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 987bcfb2eb62 d - │ ○ 12d6103dc0c8 b c - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - // The changes from the source has been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); - insta::assert_snapshot!(stdout, @r###" - c - "###); - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2"]); - insta::assert_snapshot!(stdout, @r###" - c - "###); - // File `file3`, which was not changed in source, is unchanged - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file3"]); - insta::assert_snapshot!(stdout, @r###" - d - "###); - - // Can move only part of the change in interactive mode - test_env.jj_cmd_ok(&repo_path, &["undo"]); - std::fs::write(&edit_script, "reset file2").unwrap(); - let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["move", "-i", "--from", "c"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Working copy now at: vruxwmqv 576244e8 d | (no description set) - Parent commit : qpvuntsm b7b76717 a | (no description set) - Added 0 files, modified 1 files, removed 0 files - "###); - insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 576244e87883 d - │ ○ 6f486f2f4539 c - │ ○ 12d6103dc0c8 b - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - // The selected change from the source has been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); - insta::assert_snapshot!(stdout, @r###" - c - "###); - // The unselected change from the source has not been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2"]); - insta::assert_snapshot!(stdout, @r###" - a - "###); - // File `file3`, which was changed in source's parent, is unchanged - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file3"]); - insta::assert_snapshot!(stdout, @r###" - d - "###); - - // Can move only part of the change from a sibling in non-interactive mode - test_env.jj_cmd_ok(&repo_path, &["undo"]); - // Clear the script so we know it won't be used - std::fs::write(&edit_script, "").unwrap(); - let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["move", "--from", "c", "file1"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Working copy now at: vruxwmqv 5b407c24 d | (no description set) - Parent commit : qpvuntsm b7b76717 a | (no description set) - Added 0 files, modified 1 files, removed 0 files - "###); - insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 5b407c249fa7 d - │ ○ 724d64da1487 c - │ ○ 12d6103dc0c8 b - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - // The selected change from the source has been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1"]); - insta::assert_snapshot!(stdout, @r###" - c - "###); - // The unselected change from the source has not been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2"]); - insta::assert_snapshot!(stdout, @r###" - a - "###); - // File `file3`, which was changed in source's parent, is unchanged - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file3"]); - insta::assert_snapshot!(stdout, @r###" - d - "###); - - // Can move only part of the change from a descendant in non-interactive mode - test_env.jj_cmd_ok(&repo_path, &["undo"]); - // Clear the script so we know it won't be used - std::fs::write(&edit_script, "").unwrap(); - let (stdout, stderr) = - test_env.jj_cmd_ok(&repo_path, &["move", "--from", "c", "--to", "b", "file1"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Rebased 1 descendant commits - "###); - insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - ○ d2a587ae205d c - ○ a53394306362 b - │ @ e0dac715116f d - ├─╯ - ○ b7b767179c44 a - ◆ 000000000000 - "###); - // The selected change from the source has been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file1", "-r", "b"]); - insta::assert_snapshot!(stdout, @r###" - c - "###); - // The unselected change from the source has not been applied - let stdout = test_env.jj_cmd_success(&repo_path, &["file", "show", "file2", "-r", "b"]); - insta::assert_snapshot!(stdout, @r###" - a - "###); - - // If we specify only a non-existent file, then nothing changes. - test_env.jj_cmd_ok(&repo_path, &["undo"]); - let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["move", "--from", "c", "nonexistent"]); - insta::assert_snapshot!(stdout, @""); - insta::assert_snapshot!(stderr, @r###" - Warning: `jj move` is deprecated; use `jj squash` instead, which is equivalent - Warning: `jj move` will be removed in a future version, and this will be a hard error - Nothing changed. - "###); -} - -fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String { - let template = r#"commit_id.short() ++ " " ++ bookmarks"#; - test_env.jj_cmd_success(cwd, &["log", "-T", template]) -} - -#[test] -fn test_move_description() { - let mut test_env = TestEnvironment::default(); - test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); - let repo_path = test_env.env_root().join("repo"); - - let edit_script = test_env.set_up_fake_editor(); - std::fs::write(&edit_script, r#"fail"#).unwrap(); - - // If both descriptions are empty, the resulting description is empty - std::fs::write(repo_path.join("file1"), "a\n").unwrap(); - std::fs::write(repo_path.join("file2"), "a\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["new"]); - std::fs::write(repo_path.join("file1"), "b\n").unwrap(); - std::fs::write(repo_path.join("file2"), "b\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["move", "--to", "@-"]); - insta::assert_snapshot!(get_description(&test_env, &repo_path, "@-"), @""); - - // If the destination's description is empty and the source's description is - // non-empty, the resulting description is from the source - test_env.jj_cmd_ok(&repo_path, &["undo"]); - test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "source"]); - test_env.jj_cmd_ok(&repo_path, &["move", "--to", "@-"]); - insta::assert_snapshot!(get_description(&test_env, &repo_path, "@-"), @r###" - source - "###); - - // If the destination's description is non-empty and the source's description is - // empty, the resulting description is from the destination - test_env.jj_cmd_ok(&repo_path, &["op", "restore", "@--"]); - test_env.jj_cmd_ok(&repo_path, &["describe", "@-", "-m", "destination"]); - test_env.jj_cmd_ok(&repo_path, &["move", "--to", "@-"]); - insta::assert_snapshot!(get_description(&test_env, &repo_path, "@-"), @r###" - destination - "###); - - // If both descriptions were non-empty, we get asked for a combined description - test_env.jj_cmd_ok(&repo_path, &["undo"]); - test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "source"]); - std::fs::write(&edit_script, "dump editor0").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["move", "--to", "@-"]); - insta::assert_snapshot!(get_description(&test_env, &repo_path, "@-"), @r###" - destination - - source - "###); - insta::assert_snapshot!( - std::fs::read_to_string(test_env.env_root().join("editor0")).unwrap(), @r###" - JJ: Enter a description for the combined commit. - JJ: Description from the destination commit: - destination - - JJ: Description from source commit: - source - - JJ: Lines starting with "JJ: " (like this one) will be removed. - "###); - - // If the source's *content* doesn't become empty, then the source remains and - // both descriptions are unchanged - test_env.jj_cmd_ok(&repo_path, &["undo"]); - std::fs::write(repo_path.join("file2"), "b\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["move", "--to", "@-", "file1"]); - insta::assert_snapshot!(get_description(&test_env, &repo_path, "@-"), @r###" - destination - "###); - insta::assert_snapshot!(get_description(&test_env, &repo_path, "@"), @r###" - source - "###); -} - -#[test] -fn test_move_description_editor_avoids_unc() { - let mut test_env = TestEnvironment::default(); - test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); - let repo_path = test_env.env_root().join("repo"); - - let edit_script = test_env.set_up_fake_editor(); - std::fs::write(repo_path.join("file1"), "a\n").unwrap(); - std::fs::write(repo_path.join("file2"), "a\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["new"]); - std::fs::write(repo_path.join("file1"), "b\n").unwrap(); - std::fs::write(repo_path.join("file2"), "b\n").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["describe", "@-", "-m", "destination"]); - test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "source"]); - - std::fs::write(edit_script, "dump-path path").unwrap(); - test_env.jj_cmd_ok(&repo_path, &["move", "--to", "@-"]); - - let edited_path = - PathBuf::from(std::fs::read_to_string(test_env.env_root().join("path")).unwrap()); - // While `assert!(!edited_path.starts_with("//?/"))` could work here in most - // cases, it fails when it is not safe to strip the prefix, such as paths - // over 260 chars. - assert_eq!(edited_path, dunce::simplified(&edited_path)); -} - -fn get_description(test_env: &TestEnvironment, repo_path: &Path, rev: &str) -> String { - test_env.jj_cmd_success( - repo_path, - &["log", "--no-graph", "-T", "description", "-r", rev], - ) -}