cli: include diff summary in commit/describe editor content

This commit is contained in:
Yuya Nishihara 2022-12-22 16:20:02 +09:00
parent d438f43224
commit 2550dcae4c
2 changed files with 51 additions and 7 deletions

View file

@ -1879,7 +1879,8 @@ fn cmd_describe(
} else if let Some(message) = &args.message { } else if let Some(message) = &args.message {
description = message.into() description = message.into()
} else { } 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() { if description == *commit.description() {
ui.write("Nothing changed.\n")?; 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 { let description = if let Some(message) = &args.message {
message.into() message.into()
} else { } 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); commit_builder = commit_builder.set_description(description);
let mut tx = workspace_command.start_transaction(&format!("commit {}", commit.id().hex())); 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(()) Ok(())
} }
fn description_template_for_commit(
workspace_command: &WorkspaceCommandHelper,
commit: &Commit,
) -> Result<String, CommandError> {
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( fn description_template_for_cmd_split(
workspace_command: &WorkspaceCommandHelper, workspace_command: &WorkspaceCommandHelper,
intro: &str, intro: &str,
@ -2473,13 +2496,17 @@ fn description_template_for_cmd_split(
&EverythingMatcher, &EverythingMatcher,
&[DiffFormat::Summary], &[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.", "Summary diffs and repo paths must always be valid UTF8.",
// Double-check this assumption for diffs that include file content. // 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".to_owned()
+ "JJ: This commit contains the following changes:\n" + &textwrap::indent(text, "JJ: ")
+ &textwrap::indent(diff_summary, "JJ: "))
} }
fn cmd_split(ui: &mut Ui, command: &CommandHelper, args: &SplitArgs) -> Result<(), CommandError> { fn cmd_split(ui: &mut Ui, command: &CommandHelper, args: &SplitArgs) -> Result<(), CommandError> {

View file

@ -43,7 +43,7 @@ fn test_commit_with_editor() {
// set a new one // set a new one
test_env.jj_cmd_success(&workspace_path, &["describe", "-m=initial"]); test_env.jj_cmd_success(&workspace_path, &["describe", "-m=initial"]);
let edit_script = test_env.set_up_fake_editor(); 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"]); test_env.jj_cmd_success(&workspace_path, &["commit"]);
insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###" insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###"
@ 3df78bc2b9b5 (no description set) @ 3df78bc2b9b5 (no description set)
@ -56,6 +56,23 @@ fn test_commit_with_editor() {
JJ: Lines starting with "JJ: " (like this one) will be removed. 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] #[test]