diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b1a2cef..b14295f98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj debug completion`, `jj debug mangen` and `jj debug config-schema` have been moved from `jj debug` to `jj support`. +* `jj describe` now supports `--reset-author` for resetting a commit's author + to the configured user. + ### Fixed bugs * Modify/delete conflicts now include context lines diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 4142f6aed..45e762016 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -395,7 +395,7 @@ struct InterdiffArgs { format: DiffFormatArgs, } -/// Edit the change description +/// Update the change description or other metadata /// /// Starts an editor to let you edit the description of a change. The editor /// will be $EDITOR, or `pico` if that's not defined. @@ -413,6 +413,11 @@ struct DescribeArgs { /// Read the change description from stdin #[arg(long)] stdin: bool, + /// Reset the author to the configured user + /// + /// This resets the author name, email, and timestamp. + #[arg(long)] + reset_author: bool, } /// Update the description and create a new change on top. @@ -1806,15 +1811,20 @@ fn cmd_describe( let template = description_template_for_commit(&workspace_command, &commit)?; edit_description(workspace_command.repo(), &template, command.settings())? }; - if description == *commit.description() { + if description == *commit.description() && !args.reset_author { ui.write("Nothing changed.\n")?; } else { let mut tx = workspace_command.start_transaction(&format!("describe commit {}", commit.id().hex())); - tx.mut_repo() + let mut commit_builder = tx + .mut_repo() .rewrite_commit(command.settings(), &commit) - .set_description(description) - .write()?; + .set_description(description); + if args.reset_author { + let new_author = commit_builder.committer().clone(); + commit_builder = commit_builder.set_author(new_author); + } + commit_builder.write()?; tx.finish(ui)?; } Ok(()) diff --git a/tests/test_describe_command.rs b/tests/test_describe_command.rs index 6953b4d3b..ce772acb3 100644 --- a/tests/test_describe_command.rs +++ b/tests/test_describe_command.rs @@ -141,3 +141,49 @@ fn test_describe() { .failure(); assert!(get_stderr_string(&assert).contains("bad-jj-editor-from-jj-editor-env")); } + +#[test] +fn test_describe_author() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); + let repo_path = test_env.env_root().join("repo"); + + test_env.add_config( + r#"[template-aliases] +'format_signature(signature)' = 'signature.name() ++ " " ++ signature.email() ++ " " ++ signature.timestamp()'"#, + ); + let get_signatures = || { + test_env.jj_cmd_success( + &repo_path, + &[ + "log", + "-r@", + "-T", + r#"format_signature(author) ++ "\n" ++ format_signature(committer)"#, + ], + ) + }; + insta::assert_snapshot!(get_signatures(), @r###" + @ Test User test.user@example.com 2001-02-03 04:05:07.000 +07:00 + │ Test User test.user@example.com 2001-02-03 04:05:07.000 +07:00 + ~ + "###); + + // Reset the author (the committer is always reset) + test_env.jj_cmd_success( + &repo_path, + &[ + "describe", + "--config-toml", + r#"user.name = "Ove Ridder" + user.email = "ove.ridder@example.com""#, + "-m=description", + "--reset-author", + ], + ); + insta::assert_snapshot!(get_signatures(), @r###" + @ Ove Ridder ove.ridder@example.com 2001-02-03 04:05:09.000 +07:00 + │ Ove Ridder ove.ridder@example.com 2001-02-03 04:05:09.000 +07:00 + ~ + "###); +}