-
Notifications
You must be signed in to change notification settings - Fork 353
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cli: add
--author
argument for commit
and describe
- Loading branch information
Showing
7 changed files
with
198 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3298,3 +3298,48 @@ fn format_template_aliases_hint(template_aliases: &TemplateAliasesMap) -> String | |
); | ||
hint | ||
} | ||
|
||
pub fn parse_author_arg(author: &str) -> Result<(String, String), clap::Error> { | ||
let re = regex::Regex::new(r"(?<name>.*?)\s*<(?<email>.+)>").unwrap(); | ||
let captures = re.captures(author).ok_or_else(|| { | ||
clap::error::Error::raw( | ||
clap::error::ErrorKind::InvalidValue, | ||
"Invalid author string", | ||
) | ||
})?; | ||
Ok((captures["name"].to_string(), captures["email"].to_string())) | ||
} | ||
|
||
#[cfg(test)] | ||
mod test { | ||
use super::parse_author_arg; | ||
|
||
#[test] | ||
fn test_parse_author() { | ||
let expected_name = "Example"; | ||
let expected_email = "[email protected]"; | ||
let parsed = parse_author_arg(&format!("{expected_name} <{expected_email}>")).unwrap(); | ||
assert_eq!( | ||
(expected_name.to_string(), expected_email.to_string()), | ||
parsed | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_parse_author_with_utf8() { | ||
let expected_name = "Ąćęłńóśżź"; | ||
let expected_email = "[email protected]"; | ||
let parsed = parse_author_arg(&format!("{expected_name} <{expected_email}>")).unwrap(); | ||
assert_eq!( | ||
(expected_name.to_string(), expected_email.to_string()), | ||
parsed | ||
); | ||
} | ||
|
||
#[test] | ||
fn test_parse_author_without_name() { | ||
let expected_email = "[email protected]"; | ||
let parsed = parse_author_arg(&format!("<{expected_email}>")).unwrap(); | ||
assert_eq!(("".to_string(), expected_email.to_string()), parsed); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ use jj_lib::object_id::ObjectId; | |
use jj_lib::repo::Repo; | ||
use tracing::instrument; | ||
|
||
use crate::cli_util::parse_author_arg; | ||
use crate::cli_util::CommandHelper; | ||
use crate::command_error::user_error; | ||
use crate::command_error::CommandError; | ||
|
@@ -50,6 +51,16 @@ pub(crate) struct CommitArgs { | |
/// $ JJ_USER='Foo Bar' [email protected] jj commit --reset-author | ||
#[arg(long)] | ||
reset_author: bool, | ||
/// Set author to the provided string | ||
/// | ||
/// This changes author name and email while retaining author | ||
/// timestamp if the description is filled. | ||
#[arg( | ||
long, | ||
conflicts_with = "reset_author", | ||
value_parser = parse_author_arg | ||
)] | ||
author: Option<(String, String)>, | ||
} | ||
|
||
#[instrument(skip_all)] | ||
|
@@ -106,6 +117,14 @@ new working-copy commit. | |
if args.reset_author { | ||
commit_builder.set_author(commit_builder.committer().clone()); | ||
} | ||
if let Some((name, email)) = args.author.clone() { | ||
let new_author = jj_lib::backend::Signature { | ||
name, | ||
email, | ||
timestamp: commit_builder.committer().timestamp.clone(), | ||
}; | ||
commit_builder.set_author(new_author); | ||
} | ||
|
||
let description = if !args.message_paragraphs.is_empty() { | ||
join_message_paragraphs(&args.message_paragraphs) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,10 +17,12 @@ use std::io; | |
use std::io::Read; | ||
|
||
use itertools::Itertools; | ||
use jj_lib::backend::Signature; | ||
use jj_lib::commit::CommitIteratorExt; | ||
use jj_lib::object_id::ObjectId; | ||
use tracing::instrument; | ||
|
||
use crate::cli_util::parse_author_arg; | ||
use crate::cli_util::CommandHelper; | ||
use crate::cli_util::RevisionArg; | ||
use crate::command_error::user_error; | ||
|
@@ -72,6 +74,16 @@ pub(crate) struct DescribeArgs { | |
/// $ JJ_USER='Foo Bar' [email protected] jj describe --reset-author | ||
#[arg(long)] | ||
reset_author: bool, | ||
/// Set author to the provided string | ||
/// | ||
/// This changes author name and email while retaining author | ||
/// timestamp if the description is filled. | ||
#[arg( | ||
long, | ||
conflicts_with = "reset_author", | ||
value_parser = parse_author_arg | ||
)] | ||
author: Option<(String, String)>, | ||
} | ||
|
||
#[instrument(skip_all)] | ||
|
@@ -139,6 +151,14 @@ pub(crate) fn cmd_describe( | |
let new_author = commit_builder.committer().clone(); | ||
commit_builder.set_author(new_author); | ||
} | ||
if let Some((name, email)) = args.author.clone() { | ||
let new_author = Signature { | ||
name, | ||
email, | ||
timestamp: commit.author().timestamp.clone(), | ||
}; | ||
commit_builder.set_author(new_author); | ||
} | ||
let temp_commit = commit_builder.write_hidden()?; | ||
Ok((commit.id(), temp_commit)) | ||
}) | ||
|
@@ -195,7 +215,10 @@ pub(crate) fn cmd_describe( | |
let commit_descriptions: HashMap<_, _> = commit_descriptions | ||
.into_iter() | ||
.filter_map(|(commit, new_description)| { | ||
if *new_description == *commit.description() && !args.reset_author { | ||
if *new_description == *commit.description() | ||
&& !args.reset_author | ||
&& args.author.is_none() | ||
{ | ||
None | ||
} else { | ||
Some((commit.id(), new_description)) | ||
|
@@ -225,6 +248,14 @@ pub(crate) fn cmd_describe( | |
let new_author = commit_builder.committer().clone(); | ||
commit_builder = commit_builder.set_author(new_author); | ||
} | ||
if let Some((name, email)) = args.author.clone() { | ||
let new_author = Signature { | ||
name, | ||
email, | ||
timestamp: commit_builder.author().timestamp.clone(), | ||
}; | ||
commit_builder = commit_builder.set_author(new_author); | ||
} | ||
num_described += 1; | ||
} else { | ||
num_rebased += 1; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -446,6 +446,9 @@ Update the description and create a new change on top | |
You can use it in combination with the JJ_USER and JJ_EMAIL environment variables to set a different author: | ||
$ JJ_USER='Foo Bar' [email protected] jj commit --reset-author | ||
* `--author <AUTHOR>` — Set author to the provided string | ||
This changes author name and email while retaining author timestamp if the description is filled. | ||
|
@@ -599,6 +602,9 @@ Starts an editor to let you edit the description of changes. The editor will be | |
You can use it in combination with the JJ_USER and JJ_EMAIL environment variables to set a different author: | ||
$ JJ_USER='Foo Bar' [email protected] jj describe --reset-author | ||
* `--author <AUTHOR>` — Set author to the provided string | ||
This changes author name and email while retaining author timestamp if the description is filled. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -215,6 +215,7 @@ fn test_commit_with_description_template() { | |
|
||
std::fs::write(workspace_path.join("file1"), "foo\n").unwrap(); | ||
std::fs::write(workspace_path.join("file2"), "bar\n").unwrap(); | ||
std::fs::write(workspace_path.join("file3"), "foobar\n").unwrap(); | ||
|
||
// Only file1 should be included in the diff | ||
test_env.jj_cmd_ok(&workspace_path, &["commit", "file1"]); | ||
|
@@ -230,19 +231,41 @@ fn test_commit_with_description_template() { | |
JJ: Lines starting with "JJ: " (like this one) will be removed. | ||
"###); | ||
|
||
// Timestamp after the reset should be available to the template | ||
test_env.jj_cmd_ok(&workspace_path, &["commit", "--reset-author"]); | ||
// Only file2 with modified author should be included in the diff | ||
test_env.jj_cmd_ok( | ||
&workspace_path, | ||
&[ | ||
"commit", | ||
"--author", | ||
r#""Another User <[email protected]>""#, | ||
"file2", | ||
], | ||
); | ||
insta::assert_snapshot!( | ||
std::fs::read_to_string(test_env.env_root().join("editor")).unwrap(), @r###" | ||
std::fs::read_to_string(test_env.env_root().join("editor")).unwrap(), @r#" | ||
JJ: Author: Test User <test[email protected]> (2001-02-03 08:05:09) | ||
JJ: Author: "Another User <another[email protected]> (2001-02-03 08:05:09) | ||
JJ: Committer: Test User <[email protected]> (2001-02-03 08:05:09) | ||
JJ: file2 | 1 + | ||
JJ: 1 file changed, 1 insertion(+), 0 deletions(-) | ||
JJ: Lines starting with "JJ: " (like this one) will be removed. | ||
"###); | ||
"#); | ||
|
||
// Timestamp after the reset should be available to the template | ||
test_env.jj_cmd_ok(&workspace_path, &["commit", "--reset-author"]); | ||
insta::assert_snapshot!( | ||
std::fs::read_to_string(test_env.env_root().join("editor")).unwrap(), @r#" | ||
JJ: Author: Test User <[email protected]> (2001-02-03 08:05:10) | ||
JJ: Committer: Test User <[email protected]> (2001-02-03 08:05:10) | ||
JJ: file3 | 1 + | ||
JJ: 1 file changed, 1 insertion(+), 0 deletions(-) | ||
JJ: Lines starting with "JJ: " (like this one) will be removed. | ||
"#); | ||
} | ||
|
||
#[test] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -525,29 +525,75 @@ fn test_describe_author() { | |
~ | ||
"###); | ||
|
||
// Reset the author for the latest commit (the committer is always reset) | ||
// Change the author for the latest commit (the committer is always reset) | ||
test_env.jj_cmd_ok( | ||
&repo_path, | ||
&[ | ||
"describe", | ||
"--config-toml", | ||
r#"user.name = "Ove Ridder" | ||
user.email = "[email protected]""#, | ||
"--no-edit", | ||
"--reset-author", | ||
"--author", | ||
r#""Super Seeder <[email protected]>""#, | ||
], | ||
); | ||
insta::assert_snapshot!(get_signatures(), @r###" | ||
@ Ove Ridder ove.ridder@example.com 2001-02-03 04:05:12.000 +07:00 | ||
│ Ove Ridder ove.ridder@example.com 2001-02-03 04:05:12.000 +07:00 | ||
insta::assert_snapshot!(get_signatures(), @r#" | ||
@ "Super Seeder super.seeder@example.com 2001-02-03 04:05:12.000 +07:00 | ||
│ Test User test.user@example.com 2001-02-03 04:05:12.000 +07:00 | ||
○ Test User [email protected] 2001-02-03 04:05:09.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:09.000 +07:00 | ||
○ Test User [email protected] 2001-02-03 04:05:08.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:08.000 +07:00 | ||
○ Test User [email protected] 2001-02-03 04:05:07.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:07.000 +07:00 | ||
~ | ||
"###); | ||
"#); | ||
|
||
// Change the author for multiple commits (the committer is always reset) | ||
test_env.jj_cmd_ok( | ||
&repo_path, | ||
&[ | ||
"describe", | ||
"@---", | ||
"@-", | ||
"--no-edit", | ||
"--author", | ||
r#""Super Seeder <[email protected]>""#, | ||
], | ||
); | ||
insta::assert_snapshot!(get_signatures(), @r#" | ||
@ "Super Seeder [email protected] 2001-02-03 04:05:12.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ "Super Seeder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ "Super Seeder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
~ | ||
"#); | ||
|
||
// Reset the author for the latest commit (the committer is always reset) | ||
test_env.jj_cmd_ok( | ||
&repo_path, | ||
&[ | ||
"describe", | ||
"--config-toml", | ||
r#"user.name = "Ove Ridder" | ||
user.email = "[email protected]""#, | ||
"--no-edit", | ||
"--reset-author", | ||
], | ||
); | ||
insta::assert_snapshot!(get_signatures(), @r#" | ||
@ Ove Ridder [email protected] 2001-02-03 04:05:16.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:16.000 +07:00 | ||
○ "Super Seeder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ "Super Seeder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
~ | ||
"#); | ||
|
||
// Reset the author for multiple commits (the committer is always reset) | ||
test_env.jj_cmd_ok( | ||
|
@@ -563,17 +609,17 @@ fn test_describe_author() { | |
"--reset-author", | ||
], | ||
); | ||
insta::assert_snapshot!(get_signatures(), @r###" | ||
@ Ove Ridder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ Ove Ridder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ Test User [email protected] 2001-02-03 04:05:08.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
○ Ove Ridder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
insta::assert_snapshot!(get_signatures(), @r#" | ||
@ Ove Ridder [email protected] 2001-02-03 04:05:18.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:18.000 +07:00 | ||
○ Ove Ridder [email protected] 2001-02-03 04:05:18.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:18.000 +07:00 | ||
○ Test User [email protected] 2001-02-03 04:05:14.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:18.000 +07:00 | ||
○ Ove Ridder [email protected] 2001-02-03 04:05:18.000 +07:00 | ||
│ Ove Ridder [email protected] 2001-02-03 04:05:18.000 +07:00 | ||
~ | ||
"###); | ||
"#); | ||
} | ||
|
||
#[test] | ||
|