diff --git a/cli/src/commands/operation/diff.rs b/cli/src/commands/operation/diff.rs index daf2e6c5f..7ec110bfa 100644 --- a/cli/src/commands/operation/diff.rs +++ b/cli/src/commands/operation/diff.rs @@ -222,7 +222,9 @@ pub fn show_op_diff( if !ordered_change_ids.is_empty() { writeln!(formatter)?; - writeln!(formatter, "Changed commits:")?; + with_content_format.write(formatter, |formatter| { + writeln!(formatter, "Changed commits:") + })?; if let Some(graph_style) = graph_style { let mut graph = get_graphlog(graph_style, formatter.raw()); @@ -281,14 +283,16 @@ pub fn show_op_diff( } else { for change_id in ordered_change_ids { let modified_change = changes.get(&change_id).unwrap(); - write_modified_change_summary( - formatter, - commit_summary_template, - &change_id, - modified_change, - )?; + with_content_format.write(formatter, |formatter| { + write_modified_change_summary( + formatter, + commit_summary_template, + &change_id, + modified_change, + ) + })?; if let Some(diff_renderer) = &diff_renderer { - let width = ui.term_width(); + let width = with_content_format.width(); show_change_diff(ui, formatter, diff_renderer, modified_change, width)?; } } @@ -302,25 +306,29 @@ pub fn show_op_diff( .collect_vec(); if !changed_local_bookmarks.is_empty() { writeln!(formatter)?; - writeln!(formatter, "Changed local branches:")?; + with_content_format.write(formatter, |formatter| { + writeln!(formatter, "Changed local branches:") + })?; for (name, (from_target, to_target)) in changed_local_bookmarks { - writeln!(formatter, "{}:", name)?; - write_ref_target_summary( - formatter, - current_repo, - commit_summary_template, - to_target, - true, - None, - )?; - write_ref_target_summary( - formatter, - current_repo, - commit_summary_template, - from_target, - false, - None, - )?; + with_content_format.write(formatter, |formatter| { + writeln!(formatter, "{}:", name)?; + write_ref_target_summary( + formatter, + current_repo, + commit_summary_template, + to_target, + true, + None, + )?; + write_ref_target_summary( + formatter, + current_repo, + commit_summary_template, + from_target, + false, + None, + ) + })?; } } @@ -328,25 +336,27 @@ pub fn show_op_diff( diff_named_ref_targets(from_repo.view().tags(), to_repo.view().tags()).collect_vec(); if !changed_tags.is_empty() { writeln!(formatter)?; - writeln!(formatter, "Changed tags:")?; + with_content_format.write(formatter, |formatter| writeln!(formatter, "Changed tags:"))?; for (name, (from_target, to_target)) in changed_tags { - writeln!(formatter, "{}:", name)?; - write_ref_target_summary( - formatter, - current_repo, - commit_summary_template, - to_target, - true, - None, - )?; - write_ref_target_summary( - formatter, - current_repo, - commit_summary_template, - from_target, - false, - None, - )?; + with_content_format.write(formatter, |formatter| { + writeln!(formatter, "{}:", name)?; + write_ref_target_summary( + formatter, + current_repo, + commit_summary_template, + to_target, + true, + None, + )?; + write_ref_target_summary( + formatter, + current_repo, + commit_summary_template, + from_target, + false, + None, + ) + })?; } writeln!(formatter)?; } @@ -361,29 +371,33 @@ pub fn show_op_diff( .collect_vec(); if !changed_remote_branches.is_empty() { writeln!(formatter)?; - writeln!(formatter, "Changed remote branches:")?; + with_content_format.write(formatter, |formatter| { + writeln!(formatter, "Changed remote branches:") + })?; let get_remote_ref_prefix = |remote_ref: &RemoteRef| match remote_ref.state { RemoteRefState::New => "untracked", RemoteRefState::Tracking => "tracked", }; for ((name, remote_name), (from_ref, to_ref)) in changed_remote_branches { - writeln!(formatter, "{}@{}:", name, remote_name)?; - write_ref_target_summary( - formatter, - current_repo, - commit_summary_template, - &to_ref.target, - true, - Some(get_remote_ref_prefix(to_ref)), - )?; - write_ref_target_summary( - formatter, - current_repo, - commit_summary_template, - &from_ref.target, - false, - Some(get_remote_ref_prefix(from_ref)), - )?; + with_content_format.write(formatter, |formatter| { + writeln!(formatter, "{}@{}:", name, remote_name)?; + write_ref_target_summary( + formatter, + current_repo, + commit_summary_template, + &to_ref.target, + true, + Some(get_remote_ref_prefix(to_ref)), + )?; + write_ref_target_summary( + formatter, + current_repo, + commit_summary_template, + &from_ref.target, + false, + Some(get_remote_ref_prefix(from_ref)), + ) + })?; } } diff --git a/cli/tests/test_operations.rs b/cli/tests/test_operations.rs index d0d82a78f..8d4780ed6 100644 --- a/cli/tests/test_operations.rs +++ b/cli/tests/test_operations.rs @@ -1345,6 +1345,156 @@ fn test_op_diff_sibling() { "###); } +#[test] +fn test_op_diff_word_wrap() { + let test_env = TestEnvironment::default(); + let git_repo_path = test_env.env_root().join("git-repo"); + init_bare_git_repo(&git_repo_path); + test_env.jj_cmd_ok(test_env.env_root(), &["git", "clone", "git-repo", "repo"]); + let repo_path = test_env.env_root().join("repo"); + let render = |args: &[&str], columns: u32, word_wrap: bool| { + let mut args = args.to_vec(); + if word_wrap { + args.push("--config-toml=ui.log-word-wrap=true"); + } + let assert = test_env + .jj_cmd(&repo_path, &args) + .env("COLUMNS", columns.to_string()) + .assert() + .success() + .stderr(""); + get_stdout_string(&assert) + }; + + // Add some file content changes + std::fs::write(repo_path.join("file1"), "foo\n".repeat(100)).unwrap(); + test_env.jj_cmd_ok(&repo_path, &["debug", "snapshot"]); + + // ui.log-word-wrap option works, and diff stat respects content width + insta::assert_snapshot!(render(&["op", "diff", "--from=@---", "--stat"], 40, true), @r#" + From operation b51416386f26: add workspace 'default' + To operation d12081b11443: snapshot working copy + + Changed commits: + ○ Change sqpuoqvxutmz + │ + sqpuoqvx 850efc9e (no description + │ set) + │ file1 | 100 ++++++++++++++++++++++ + │ 1 file changed, 100 insertions(+), 0 deletions(-) + ○ Change ulyvmwyzwuwt + + ulyvmwyz 1d843d1f bookmark-1 | + Commit 1 + some-file | 1 + + 1 file changed, 1 insertion(+), 0 deletions(-) + ○ Change tqyxmsztkvot + + tqyxmszt 3e785984 bookmark-3@origin + | Commit 3 + some-file | 1 + + 1 file changed, 1 insertion(+), 0 deletions(-) + ○ Change yuvsmzqkmpws + + yuvsmzqk 3d9189bc bookmark-2@origin + | Commit 2 + some-file | 1 + + 1 file changed, 1 insertion(+), 0 deletions(-) + ○ Change qpvuntsmwlqt + - qpvuntsm hidden 230dd059 (empty) + (no description set) + 0 files changed, 0 insertions(+), 0 deletions(-) + + Changed local branches: + bookmark-1: + + ulyvmwyz 1d843d1f bookmark-1 | Commit + 1 + - (absent) + + Changed remote branches: + bookmark-1@origin: + + tracked ulyvmwyz 1d843d1f bookmark-1 | + Commit 1 + - untracked (absent) + bookmark-2@origin: + + untracked yuvsmzqk 3d9189bc + bookmark-2@origin | Commit 2 + - untracked (absent) + bookmark-3@origin: + + untracked tqyxmszt 3e785984 + bookmark-3@origin | Commit 3 + - untracked (absent) + "#); + + // Graph width should be subtracted from the term width + let config = r#"templates.commit_summary='"0 1 2 3 4 5 6 7 8 9"'"#; + insta::assert_snapshot!( + render(&["op", "diff", "--from=@---", "--config-toml", config], 10, true), @r#" + From operation b51416386f26: add workspace 'default' + To operation d12081b11443: snapshot working copy + + Changed + commits: + ○ Change + │ sqpuoqvxutmz + │ + 0 1 2 + │ 3 4 5 6 + │ 7 8 9 + ○ Change + ulyvmwyzwuwt + + 0 1 2 + 3 4 5 6 + 7 8 9 + ○ Change + tqyxmsztkvot + + 0 1 2 + 3 4 5 6 + 7 8 9 + ○ Change + yuvsmzqkmpws + + 0 1 2 + 3 4 5 6 + 7 8 9 + ○ Change + qpvuntsmwlqt + - 0 1 2 + 3 4 5 6 + 7 8 9 + + Changed + local + branches: + bookmark-1: + + 0 1 2 3 + 4 5 6 7 8 + 9 + - (absent) + + Changed + remote + branches: + bookmark-1@origin: + + tracked + 0 1 2 3 4 + 5 6 7 8 9 + - + untracked + (absent) + bookmark-2@origin: + + + untracked + 0 1 2 3 4 + 5 6 7 8 9 + - + untracked + (absent) + bookmark-3@origin: + + + untracked + 0 1 2 3 4 + 5 6 7 8 9 + - + untracked + (absent) + "#); +} + #[test] fn test_op_show() { let test_env = TestEnvironment::default();