Include file list when editing split commit description

Example:

        JJ: Enter commit description for the first part (parent).
        Better split commit message

        JJ: This part contains the following changes:
        JJ:   M src/formatter.rs
        JJ:
        JJ: Lines starting with "JJ: " (like this one) will be removed.
This commit is contained in:
Ilya Grigoriev 2022-11-05 13:37:23 -07:00
parent a86de96bd4
commit cf3b6ee2c9

View file

@ -56,7 +56,7 @@ use crate::cli_util::{
write_commit_summary, Args, CommandError, CommandHelper, WorkspaceCommandHelper,
};
use crate::commands::CommandError::UserError;
use crate::formatter::Formatter;
use crate::formatter::{Formatter, PlainTextFormatter};
use crate::graphlog::{AsciiGraphDrawer, Edge};
use crate::progress::Progress;
use crate::template_parser::TemplateParser;
@ -1436,6 +1436,17 @@ fn show_diff(
Ok(())
}
fn diff_as_bytes(
workspace_command: &WorkspaceCommandHelper,
tree_diff: TreeDiffIterator,
format: DiffFormat,
) -> Result<Vec<u8>, CommandError> {
let mut diff_bytes: Vec<u8> = vec![];
let mut formatter = PlainTextFormatter::new(&mut diff_bytes);
show_diff(&mut formatter, workspace_command, tree_diff, format)?;
Ok(diff_bytes)
}
fn diff_content(
repo: &Arc<ReadonlyRepo>,
path: &RepoPath,
@ -2883,6 +2894,22 @@ don't make any changes, then the operation will be aborted.",
Ok(())
}
fn description_template_for_cmd_split(
workspace_command: &WorkspaceCommandHelper,
intro: &str,
overall_commit_description: &str,
diff_iter: TreeDiffIterator,
) -> Result<String, CommandError> {
let diff_summary_bytes = diff_as_bytes(workspace_command, diff_iter, DiffFormat::Summary)?;
let diff_summary = std::str::from_utf8(&diff_summary_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 part contains the following changes:\n"
+ &textwrap::indent(diff_summary, "JJ: "))
}
fn cmd_split(ui: &mut Ui, command: &CommandHelper, args: &SplitArgs) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision)?;
@ -2914,22 +2941,29 @@ don't make any changes, then the operation will be aborted.
} else {
let mut tx =
workspace_command.start_transaction(&format!("split commit {}", commit.id().hex()));
let first_description = edit_description(
ui,
tx.base_repo(),
&("JJ: Enter commit description for the first part.\n".to_string()
+ commit.description()),
let middle_tree = workspace_command
.repo()
.store()
.get_tree(&RepoPath::root(), &tree_id)?;
let first_template = description_template_for_cmd_split(
&workspace_command,
"Enter commit description for the first part (parent).",
commit.description(),
base_tree.diff(&middle_tree, &EverythingMatcher),
)?;
let first_description = edit_description(ui, tx.base_repo(), &first_template)?;
let first_commit = CommitBuilder::for_rewrite_from(ui.settings(), &commit)
.set_tree(tree_id)
.set_description(first_description)
.write_to_repo(tx.mut_repo());
let second_description = edit_description(
ui,
tx.base_repo(),
&("JJ: Enter commit description for the second part.\n".to_string()
+ commit.description()),
let second_template = description_template_for_cmd_split(
&workspace_command,
"Enter commit description for the second part (child).",
commit.description(),
middle_tree.diff(&commit.tree(), &EverythingMatcher),
)?;
let second_description = edit_description(ui, tx.base_repo(), &second_template)?;
let second_commit = CommitBuilder::for_rewrite_from(ui.settings(), &commit)
.set_parents(vec![first_commit.id().clone()])
.set_tree(commit.tree_id().clone())