diff --git a/CHANGELOG.md b/CHANGELOG.md index d76850bc7..e06922cdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). respectively to `true` or `false`. * All diff formats except `--name-only` now include information about copies and - moves. So do external diff tools in file-by-file mode. + moves. So do external diff tools in file-by-file mode. `jj status` also + includes information about copies and moves. * Color-words diff has gained [an option to display complex changes as separate lines](docs/config.md#color-words-diff-options). diff --git a/cli/src/commands/status.rs b/cli/src/commands/status.rs index 81c1eab68..c367474a8 100644 --- a/cli/src/commands/status.rs +++ b/cli/src/commands/status.rs @@ -13,6 +13,7 @@ // limitations under the License. use itertools::Itertools; +use jj_lib::copies::CopyRecords; use jj_lib::repo::Repo; use jj_lib::revset::RevsetExpression; use jj_lib::revset::RevsetFilterPredicate; @@ -21,6 +22,7 @@ use tracing::instrument; use crate::cli_util::print_conflicted_paths; use crate::cli_util::CommandHelper; use crate::command_error::CommandError; +use crate::diff_util::get_copy_records; use crate::diff_util::DiffFormat; use crate::revset_util; use crate::ui::Ui; @@ -67,6 +69,11 @@ pub(crate) fn cmd_status( writeln!(formatter, "The working copy is clean")?; } else { writeln!(formatter, "Working copy changes:")?; + let mut copy_records = CopyRecords::default(); + for parent in wc_commit.parent_ids() { + let records = get_copy_records(repo.store(), parent, wc_commit.id(), &matcher)?; + copy_records.add_records(records)?; + } let diff_renderer = workspace_command.diff_renderer(vec![DiffFormat::Summary]); let width = ui.term_width(); diff_renderer.show_diff( @@ -75,7 +82,7 @@ pub(crate) fn cmd_status( &parent_tree, &tree, &matcher, - &Default::default(), + ©_records, width, )?; } diff --git a/cli/tests/test_status_command.rs b/cli/tests/test_status_command.rs index 1e84bb931..2a7ae347f 100644 --- a/cli/tests/test_status_command.rs +++ b/cli/tests/test_status_command.rs @@ -36,6 +36,39 @@ fn create_commit( test_env.jj_cmd_ok(repo_path, &["branch", "create", name]); } +#[test] +fn test_status_copies() { + 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"); + + std::fs::write(repo_path.join("copy-source"), "copy1\ncopy2\ncopy3\n").unwrap(); + std::fs::write(repo_path.join("rename-source"), "rename").unwrap(); + test_env.jj_cmd_ok(&repo_path, &["new"]); + std::fs::write( + repo_path.join("copy-source"), + "copy1\ncopy2\ncopy3\nsource\n", + ) + .unwrap(); + std::fs::write( + repo_path.join("copy-target"), + "copy1\ncopy2\ncopy3\ntarget\n", + ) + .unwrap(); + std::fs::remove_file(repo_path.join("rename-source")).unwrap(); + std::fs::write(repo_path.join("rename-target"), "rename").unwrap(); + + let stdout = test_env.jj_cmd_success(&repo_path, &["status"]); + insta::assert_snapshot!(stdout, @r###" + Working copy changes: + M copy-source + C {copy-source => copy-target} + R {rename-source => rename-target} + Working copy : rlvkpnrz a96c3086 (no description set) + Parent commit: qpvuntsm e3e2c703 (no description set) + "###); +} + #[test] fn test_status_merge() { let test_env = TestEnvironment::default();