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 {
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<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(
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> {

View file

@ -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]