From 2550dcae4cfe2a97452b49ef680625f57f6ab809 Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Thu, 22 Dec 2022 16:20:02 +0900 Subject: [PATCH] cli: include diff summary in commit/describe editor content --- src/commands.rs | 39 ++++++++++++++++++++++++++++++------ tests/test_commit_command.rs | 19 +++++++++++++++++- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 088d1d2c7..6483623b3 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1879,7 +1879,8 @@ fn cmd_describe( } else if let Some(message) = &args.message { description = message.into() } else { - description = edit_description(ui, workspace_command.repo(), commit.description())?; + let template = description_template_for_commit(&workspace_command, &commit)?; + description = edit_description(ui, workspace_command.repo(), &template)?; } if description == *commit.description() { ui.write("Nothing changed.\n")?; @@ -1908,7 +1909,8 @@ fn cmd_commit(ui: &mut Ui, command: &CommandHelper, args: &CommitArgs) -> Result let description = if let Some(message) = &args.message { message.into() } else { - edit_description(ui, workspace_command.repo(), commit.description())? + let template = description_template_for_commit(&workspace_command, &commit)?; + edit_description(ui, workspace_command.repo(), &template)? }; commit_builder = commit_builder.set_description(description); let mut tx = workspace_command.start_transaction(&format!("commit {}", commit.id().hex())); @@ -2457,6 +2459,27 @@ don't make any changes, then the operation will be aborted.", Ok(()) } +fn description_template_for_commit( + workspace_command: &WorkspaceCommandHelper, + commit: &Commit, +) -> Result { + let mut diff_summary_bytes = Vec::new(); + diff_util::show_patch( + &mut PlainTextFormatter::new(&mut diff_summary_bytes), + workspace_command, + commit, + &EverythingMatcher, + &[DiffFormat::Summary], + )?; + if diff_summary_bytes.is_empty() { + Ok(commit.description().to_owned()) + } else { + Ok(commit.description().to_owned() + + "\n" + + &diff_summary_to_description(&diff_summary_bytes)) + } +} + fn description_template_for_cmd_split( workspace_command: &WorkspaceCommandHelper, intro: &str, @@ -2473,13 +2496,17 @@ fn description_template_for_cmd_split( &EverythingMatcher, &[DiffFormat::Summary], )?; - let diff_summary = std::str::from_utf8(&diff_summary_bytes).expect( + Ok(format!("JJ: {intro}\n{overall_commit_description}\n") + + &diff_summary_to_description(&diff_summary_bytes)) +} + +fn diff_summary_to_description(bytes: &[u8]) -> String { + let text = std::str::from_utf8(bytes).expect( "Summary diffs and repo paths must always be valid UTF8.", // Double-check this assumption for diffs that include file content. ); - Ok(format!("JJ: {intro}\n{overall_commit_description}\n") - + "JJ: This commit contains the following changes:\n" - + &textwrap::indent(diff_summary, "JJ: ")) + "JJ: This commit contains the following changes:\n".to_owned() + + &textwrap::indent(text, "JJ: ") } fn cmd_split(ui: &mut Ui, command: &CommandHelper, args: &SplitArgs) -> Result<(), CommandError> { diff --git a/tests/test_commit_command.rs b/tests/test_commit_command.rs index 64f8c51d2..1088c6458 100644 --- a/tests/test_commit_command.rs +++ b/tests/test_commit_command.rs @@ -43,7 +43,7 @@ fn test_commit_with_editor() { // set a new one test_env.jj_cmd_success(&workspace_path, &["describe", "-m=initial"]); let edit_script = test_env.set_up_fake_editor(); - std::fs::write(edit_script, ["dump editor0", "write\nmodified"].join("\0")).unwrap(); + std::fs::write(&edit_script, ["dump editor0", "write\nmodified"].join("\0")).unwrap(); test_env.jj_cmd_success(&workspace_path, &["commit"]); insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###" @ 3df78bc2b9b5 (no description set) @@ -56,6 +56,23 @@ fn test_commit_with_editor() { JJ: Lines starting with "JJ: " (like this one) will be removed. "###); + + // Check that the editor content includes diff summary + std::fs::write(workspace_path.join("file1"), "foo\n").unwrap(); + std::fs::write(workspace_path.join("file2"), "foo\n").unwrap(); + test_env.jj_cmd_success(&workspace_path, &["describe", "-m=add files"]); + std::fs::write(&edit_script, "dump editor1").unwrap(); + test_env.jj_cmd_success(&workspace_path, &["commit"]); + insta::assert_snapshot!( + std::fs::read_to_string(test_env.env_root().join("editor1")).unwrap(), @r###" + add files + + JJ: This commit contains the following changes: + JJ: A file1 + JJ: A file2 + + JJ: Lines starting with "JJ: " (like this one) will be removed. + "###); } #[test]