From 223470295e2ed2ecf3cbe59148a8967ecf6b642f Mon Sep 17 00:00:00 2001 From: David Higgs Date: Sun, 21 Dec 2025 08:08:22 -0500 Subject: [PATCH] cli: remove newline addition between template and content Commands `jj log`, `jj evolog`, and `jj op log` automatically added a terminating newline when the expanded template did not include one in graph mode. No-graph mode did not do this, so the expanded template could combine with any following content (diff, op changes, etc) in confusing or problematic ways. Instead of trying to compensate in all cases, remove the auto-fixups. Users should confirm their custom templates still expand correctly for their needs. --- CHANGELOG.md | 3 +++ cli/src/commands/evolog.rs | 3 --- cli/src/commands/log.rs | 3 --- cli/src/commands/operation/diff.rs | 4 ---- cli/src/commands/operation/log.rs | 3 --- cli/tests/test_diff_command.rs | 12 +++++------- cli/tests/test_log_command.rs | 8 +++----- cli/tests/test_operations.rs | 1 - cli/tests/test_squash_command.rs | 3 +-- 9 files changed, 12 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87b1e4b8d..ce6ee9c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). * The deprecated `commit_id.normal_hex()` template method has been removed. +* Template expansion that did not produce a terminating newline will not be + fixed up to provide one by `jj log`, `jj evolog`, or `jj op log`. + ### Deprecations * The `git_head()` and `git_refs()` functions will be removed from revsets and diff --git a/cli/src/commands/evolog.rs b/cli/src/commands/evolog.rs index c65e8dc00..20f352fb4 100644 --- a/cli/src/commands/evolog.rs +++ b/cli/src/commands/evolog.rs @@ -174,9 +174,6 @@ pub(crate) fn cmd_evolog( within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { template.format(&entry, formatter) })?; - if !buffer.ends_with(b"\n") { - buffer.push(b'\n'); - } if let Some(renderer) = &diff_renderer { let predecessors: Vec<_> = entry.predecessors().try_collect()?; let mut formatter = ui.new_formatter(&mut buffer); diff --git a/cli/src/commands/log.rs b/cli/src/commands/log.rs index 093da0d49..fc90911cb 100644 --- a/cli/src/commands/log.rs +++ b/cli/src/commands/log.rs @@ -273,9 +273,6 @@ pub(crate) fn cmd_log( within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { template.format(&commit, formatter) })?; - if !buffer.ends_with(b"\n") { - buffer.push(b'\n'); - } if let Some(renderer) = &diff_renderer { let mut formatter = ui.new_formatter(&mut buffer); renderer diff --git a/cli/src/commands/operation/diff.rs b/cli/src/commands/operation/diff.rs index 801ab79c3..cf9396e3a 100644 --- a/cli/src/commands/operation/diff.rs +++ b/cli/src/commands/operation/diff.rs @@ -208,9 +208,6 @@ pub fn show_op_diff( modified_change, ) })?; - if !buffer.ends_with(b"\n") { - buffer.push(b'\n'); - } if let Some(diff_renderer) = diff_renderer { let mut formatter = ui.new_formatter(&mut buffer); show_change_diff( @@ -346,7 +343,6 @@ pub fn show_op_diff( ) })?; } - writeln!(formatter)?; } let ignored_remote = default_ignored_remote_name(current_repo.store()); diff --git a/cli/src/commands/operation/log.rs b/cli/src/commands/operation/log.rs index ad88925d4..d805fa161 100644 --- a/cli/src/commands/operation/log.rs +++ b/cli/src/commands/operation/log.rs @@ -223,9 +223,6 @@ fn do_op_log( within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| { template.format(&op, formatter) })?; - if !buffer.ends_with(b"\n") { - buffer.push(b'\n'); - } if let Some(show) = &maybe_show_op_diff { let mut formatter = ui.new_formatter(&mut buffer); show(ui, formatter.as_mut(), &op, &within_graph)?; diff --git a/cli/tests/test_diff_command.rs b/cli/tests/test_diff_command.rs index 6de4c31f8..ef6e51fdd 100644 --- a/cli/tests/test_diff_command.rs +++ b/cli/tests/test_diff_command.rs @@ -3319,13 +3319,11 @@ fn test_diff_external_available_width() { cmd.args(["log", "--tool=echo", "-T''"]) .env("COLUMNS", "50") }); - insta::assert_snapshot!(output, @r" - @ - │ 47 - │ ○ - ├─╯ 45 - ◆ - 47 + insta::assert_snapshot!(output, @" + @ 47 + │ ○ 45 + ├─╯ + ◆ 47 [EOF] "); } diff --git a/cli/tests/test_log_command.rs b/cli/tests/test_log_command.rs index ae060efae..dd26104d6 100644 --- a/cli/tests/test_log_command.rs +++ b/cli/tests/test_log_command.rs @@ -237,14 +237,13 @@ fn test_log_with_or_without_diff() { │ 1 file changed, 1 insertion(+), 0 deletions(-) │ Added regular file file1: │ 1: foo - ◆ - 0 files changed, 0 insertions(+), 0 deletions(-) + ◆ 0 files changed, 0 insertions(+), 0 deletions(-) [EOF] "); // `--stat` is short format, which should be printed first let output = work_dir.run_jj(["log", "-T", "description", "--git", "--stat"]); - insta::assert_snapshot!(output, @r" + insta::assert_snapshot!(output, @" @ a new commit │ file1 | 1 + │ 1 file changed, 1 insertion(+), 0 deletions(-) @@ -265,8 +264,7 @@ fn test_log_with_or_without_diff() { │ +++ b/file1 │ @@ -0,0 +1,1 @@ │ +foo - ◆ - 0 files changed, 0 insertions(+), 0 deletions(-) + ◆ 0 files changed, 0 insertions(+), 0 deletions(-) [EOF] "); diff --git a/cli/tests/test_operations.rs b/cli/tests/test_operations.rs index 6c243c757..5bb609139 100644 --- a/cli/tests/test_operations.rs +++ b/cli/tests/test_operations.rs @@ -601,7 +601,6 @@ fn test_op_log_word_wrap() { insta::assert_snapshot!( render(&["op", "log", "-T''", "--op-diff", "-n1", "--config", config], 15, true), @r" @ - │ │ Changed │ commits: │ ○ + 0 1 2 3 diff --git a/cli/tests/test_squash_command.rs b/cli/tests/test_squash_command.rs index 3bfd5fd29..852a381d2 100644 --- a/cli/tests/test_squash_command.rs +++ b/cli/tests/test_squash_command.rs @@ -2111,8 +2111,7 @@ fn test_squash_to_new_commit() { │ A file2 ○ qpvuntsmwlqt bm1 file1 │ A file1 - ○ soqnvnyzoxuu - │ A file3 + ○ soqnvnyzoxuuA file3 │ A file4 ◆ zzzzzzzzzzzz [EOF]