diff --git a/CHANGELOG.md b/CHANGELOG.md index c5c7a8af3..e7d3325fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * When sharing the working copy with a Git repo, we used to forget to export branches to Git when only the working copy had changed. That's now fixed. +* Commit description set by `-m`/`--message` is now terminated with a newline + character, just like descriptions set by editor are. + ### Contributors Thanks to the people who made this release happen! diff --git a/src/cli_util.rs b/src/cli_util.rs index b9fe839f6..f2f2e1805 100644 --- a/src/cli_util.rs +++ b/src/cli_util.rs @@ -1344,6 +1344,44 @@ pub struct EarlyArgs { pub config_toml: Vec, } +/// `-m/--message` argument which should be terminated with `\n`. +/// +/// Based on the Git CLI behavior. See `opt_parse_m()` and `cleanup_mode` in +/// `git/builtin/commit.c`. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct DescriptionArg(String); + +impl DescriptionArg { + pub fn as_str(&self) -> &str { + self.0.as_str() + } +} + +impl From for DescriptionArg { + fn from(mut s: String) -> Self { + complete_newline(&mut s); + DescriptionArg(s) + } +} + +impl From<&DescriptionArg> for String { + fn from(arg: &DescriptionArg) -> Self { + arg.0.to_owned() + } +} + +impl AsRef for DescriptionArg { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +fn complete_newline(s: &mut String) { + if !s.is_empty() && !s.ends_with('\n') { + s.push('\n'); + } +} + #[derive(Clone, Debug)] pub struct RevisionArg(String); diff --git a/src/commands.rs b/src/commands.rs index 721d68d34..b296ef2ef 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -53,7 +53,8 @@ use pest::Parser; use crate::cli_util::{ check_stale_working_copy, print_checkout_stats, print_failed_git_export, resolve_base_revs, short_commit_description, short_commit_hash, user_error, user_error_with_hint, - write_commit_summary, Args, CommandError, CommandHelper, RevisionArg, WorkspaceCommandHelper, + write_commit_summary, Args, CommandError, CommandHelper, DescriptionArg, RevisionArg, + WorkspaceCommandHelper, }; use crate::config::FullCommandArgs; use crate::diff_util::{self, DiffFormat, DiffFormatArgs}; @@ -155,7 +156,7 @@ struct CheckoutArgs { unused_revision: bool, /// The change description to use #[arg(long, short, default_value = "")] - message: String, + message: DescriptionArg, } /// Stop tracking specified paths in the working copy @@ -330,7 +331,7 @@ struct DescribeArgs { unused_revision: bool, /// The change description to use (don't open editor) #[arg(long, short)] - message: Option, + message: Option, /// Read the change description from stdin #[arg(long)] stdin: bool, @@ -342,7 +343,7 @@ struct DescribeArgs { struct CommitArgs { /// The change description to use (don't open editor) #[arg(long, short)] - message: Option, + message: Option, } /// Create a new change with the same content as an existing one @@ -403,7 +404,7 @@ struct NewArgs { unused_revision: bool, /// The change description to use #[arg(long, short, default_value = "")] - message: String, + message: DescriptionArg, } /// Move changes from one revision into another @@ -1877,7 +1878,7 @@ fn cmd_describe( io::stdin().read_to_string(&mut buffer).unwrap(); description = buffer; } else if let Some(message) = &args.message { - description = message.to_owned() + description = message.into() } else { description = edit_description(ui, workspace_command.repo(), commit.description())?; } @@ -1906,7 +1907,7 @@ fn cmd_commit(ui: &mut Ui, command: &CommandHelper, args: &CommitArgs) -> Result let mut commit_builder = CommitBuilder::for_rewrite_from(ui.settings(), &commit); let description = if let Some(message) = &args.message { - message.to_string() + message.into() } else { edit_description(ui, workspace_command.repo(), commit.description())? }; diff --git a/tests/test_checkout.rs b/tests/test_checkout.rs index 97d234567..c71c673d7 100644 --- a/tests/test_checkout.rs +++ b/tests/test_checkout.rs @@ -30,22 +30,22 @@ fn test_checkout() { // Check out current commit let stdout = test_env.jj_cmd_success(&repo_path, &["checkout", "@"]); insta::assert_snapshot!(stdout, @r###" - Working copy now at: 66f7f3f8235b (no description set) + Working copy now at: 05ce7118568d (no description set) "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 66f7f3f8235beaed90345fe93c5a86c30f4f026f (no description set) - o 91043abe9d0385a279102350df38807f4aa053b7 second - o 85a1e2839620cf0b354d1ccb970927d040c2a4a7 first + @ 05ce7118568d3007efc9163b055f9cb4a6becfde (no description set) + o 5c52832c3483e0ace06d047a806024984f28f1d7 second + o 69542c1984c1f9d91f7c6c9c9e6941782c944bd9 first o 0000000000000000000000000000000000000000 (no description set) "###); // Can provide a description test_env.jj_cmd_success(&repo_path, &["checkout", "@--", "-m", "my message"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 44f21384b2b12735d9477ec8b406bd4e48047c41 my message - | o 91043abe9d0385a279102350df38807f4aa053b7 second + @ 1191baaf276e3d0b96b1747e885b3a517be80d6f my message + | o 5c52832c3483e0ace06d047a806024984f28f1d7 second |/ - o 85a1e2839620cf0b354d1ccb970927d040c2a4a7 first + o 69542c1984c1f9d91f7c6c9c9e6941782c944bd9 first o 0000000000000000000000000000000000000000 (no description set) "###); } @@ -66,11 +66,11 @@ fn test_checkout_not_single_rev() { insta::assert_snapshot!(stderr, @r###" Error: Revset "root..@" resolved to more than one revision Hint: The revset resolved to these revisions: - eb01ec3263be () - 17b6965c1349 (fifth) - f8381c76d1d3 (fourth) - ca3820f77363 (third) - 91043abe9d03 (second) + 2f8593712db5 () + 5c1afd8b074f (fifth) + 009f88bf7141 (fourth) + 3fa8931e7b89 (third) + 5c52832c3483 (second) ... "###); @@ -78,19 +78,19 @@ fn test_checkout_not_single_rev() { insta::assert_snapshot!(stderr, @r###" Error: Revset "root..@-" resolved to more than one revision Hint: The revset resolved to these revisions: - 17b6965c1349 (fifth) - f8381c76d1d3 (fourth) - ca3820f77363 (third) - 91043abe9d03 (second) - 85a1e2839620 (first) + 5c1afd8b074f (fifth) + 009f88bf7141 (fourth) + 3fa8931e7b89 (third) + 5c52832c3483 (second) + 69542c1984c1 (first) "###); let stderr = test_env.jj_cmd_failure(&repo_path, &["checkout", "@-|@--"]); insta::assert_snapshot!(stderr, @r###" Error: Revset "@-|@--" resolved to more than one revision Hint: The revset resolved to these revisions: - 17b6965c1349 (fifth) - f8381c76d1d3 (fourth) + 5c1afd8b074f (fifth) + 009f88bf7141 (fourth) "###); let stderr = test_env.jj_cmd_failure(&repo_path, &["checkout", "none()"]); diff --git a/tests/test_commit_command.rs b/tests/test_commit_command.rs index 5aea9b0c6..abdd60661 100644 --- a/tests/test_commit_command.rs +++ b/tests/test_commit_command.rs @@ -27,8 +27,8 @@ fn test_commit_with_description_from_cli() { // Description applies to the current working-copy (not the new one) test_env.jj_cmd_success(&workspace_path, &["commit", "-m=first"]); insta::assert_snapshot!(get_log_output(&test_env, &workspace_path), @r###" - @ 69e88fe3e63b (no description set) - o 85a1e2839620 first + @ b88fb4e51bdd (no description set) + o 69542c1984c1 first o 000000000000 (no description set) "###); } @@ -47,6 +47,7 @@ fn test_commit_with_editor() { edit_script, "expect initial + JJ: Lines starting with \"JJ: \" (like this one) will be removed. \0write modified", diff --git a/tests/test_concurrent_operations.rs b/tests/test_concurrent_operations.rs index de3e39d11..6342fc1e0 100644 --- a/tests/test_concurrent_operations.rs +++ b/tests/test_concurrent_operations.rs @@ -51,7 +51,7 @@ fn test_concurrent_operations_auto_rebase() { test_env.jj_cmd_success(&repo_path, &["describe", "-m", "initial"]); let stdout = test_env.jj_cmd_success(&repo_path, &["op", "log"]); insta::assert_snapshot!(stdout, @r###" - @ 72fc1a08c327 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00 + @ 9e80a32ef376 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00 | describe commit 123ed18e4c4c0d77428df41112bc02ffc83fb935 | args: jj describe -m initial o b9a339dcd1dc test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00 @@ -74,8 +74,8 @@ fn test_concurrent_operations_auto_rebase() { insta::assert_snapshot!(stdout, @r###" Concurrent modification detected, resolving automatically. Rebased 1 descendant commits onto commits rewritten by other operation - o 4eeb7d76372418118a91c34f09e5e3936f0deeb5 new child - @ 14176aeadc0259b2150fc7374969e74b1552a498 rewritten + o 3f06323826b4a293a9ee6d24cc0e07ad2961b5d5 new child + @ d91437157468ec86bbbc9e6a14a60d3e8d1790ac rewritten o 0000000000000000000000000000000000000000 (no description set) "###); } @@ -105,10 +105,10 @@ fn test_concurrent_operations_wc_modified() { let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "commit_id \" \" description"]); insta::assert_snapshot!(stdout, @r###" Concurrent modification detected, resolving automatically. - @ 304d2b4b70536e0bfd7a38394db584ee069a3b1a new child1 - | o ac08e56f9b802269864c5061f2a7305b9258a671 new child2 + @ 4eb0610031b7cd148ff9f729a673a3f815033170 new child1 + | o 4b20e61d23ee7d7c4d5e61e11e97c26e716f9c30 new child2 |/ - o 5af56dcc2cc27bb234e5574b5a3ebc5f22081462 initial + o 52c893bf3cd201e215b23e084e8a871244ca14d5 initial o 0000000000000000000000000000000000000000 (no description set) "###); let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "--git"]); diff --git a/tests/test_describe_command.rs b/tests/test_describe_command.rs index af6f7cdf8..41b87e98a 100644 --- a/tests/test_describe_command.rs +++ b/tests/test_describe_command.rs @@ -27,7 +27,13 @@ fn test_describe() { // Set a description using `-m` flag let stdout = test_env.jj_cmd_success(&repo_path, &["describe", "-m", "description from CLI"]); insta::assert_snapshot!(stdout, @r###" - Working copy now at: 7e0db3b0ad17 description from CLI + Working copy now at: cf3e86731c67 description from CLI + "###); + + // Set the same description using `-m` flag, but with explicit newline + let stdout = test_env.jj_cmd_success(&repo_path, &["describe", "-m", "description from CLI\n"]); + insta::assert_snapshot!(stdout, @r###" + Nothing changed. "###); // Check that the text file gets initialized with the current description and @@ -36,20 +42,21 @@ fn test_describe() { &edit_script, r#"expect description from CLI + JJ: Lines starting with "JJ: " (like this one) will be removed. "#, ) .unwrap(); let stdout = test_env.jj_cmd_success(&repo_path, &["describe"]); insta::assert_snapshot!(stdout, @r###" - Working copy now at: 45bfa10db64d description from CLI + Nothing changed. "###); // Set a description in editor std::fs::write(&edit_script, "write\ndescription from editor").unwrap(); let stdout = test_env.jj_cmd_success(&repo_path, &["describe"]); insta::assert_snapshot!(stdout, @r###" - Working copy now at: f2ce8f1ad8fa description from editor + Working copy now at: bfdd972f9349 description from editor "###); // Lines in editor starting with "JJ: " are ignored @@ -60,7 +67,7 @@ JJ: Lines starting with "JJ: " (like this one) will be removed. .unwrap(); let stdout = test_env.jj_cmd_success(&repo_path, &["describe"]); insta::assert_snapshot!(stdout, @r###" - Working copy now at: 95664f6316ae description among comment + Working copy now at: ccefa58bef47 description among comment "###); // Fails if the editor fails diff --git a/tests/test_diffedit_command.rs b/tests/test_diffedit_command.rs index 46494bd11..d35d00fa9 100644 --- a/tests/test_diffedit_command.rs +++ b/tests/test_diffedit_command.rs @@ -149,9 +149,9 @@ fn test_diffedit_merge() { .unwrap(); let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit", "-r", "@-"]); insta::assert_snapshot!(stdout, @r###" - Created cb2b3b755c0a merge + Created a70eded7af9e merge Rebased 1 descendant commits - Working copy now at: 9c86af62d473 (no description set) + Working copy now at: a5f1ce845f74 (no description set) Added 0 files, modified 0 files, removed 1 files "###); let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s", "-r", "@-"]); diff --git a/tests/test_edit_command.rs b/tests/test_edit_command.rs index 8a5bbcaed..dfdc15e7c 100644 --- a/tests/test_edit_command.rs +++ b/tests/test_edit_command.rs @@ -42,12 +42,12 @@ fn test_edit() { // Makes the specified commit the working-copy commit let stdout = test_env.jj_cmd_success(&repo_path, &["edit", "@-"]); insta::assert_snapshot!(stdout, @r###" - Working copy now at: 5c9d6c787f29 first + Working copy now at: f41390a5efbf first Added 0 files, modified 1 files, removed 0 files "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - o 37ed5225d0fd second - @ 5c9d6c787f29 first + o b2f7e9c549aa second + @ f41390a5efbf first o 000000000000 (no description set) "###); insta::assert_snapshot!(read_file(&repo_path.join("file1")), @"0"); @@ -56,8 +56,8 @@ fn test_edit() { std::fs::write(repo_path.join("file2"), "0").unwrap(); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" Rebased 1 descendant commits onto updated working copy - o 57e61f6b2ce1 second - @ f1b9706b17d0 first + o 51d937a3eeb4 second + @ 409306de8f44 first o 000000000000 (no description set) "###); } diff --git a/tests/test_git_colocated.rs b/tests/test_git_colocated.rs index 6c5694f71..0d6fc168c 100644 --- a/tests/test_git_colocated.rs +++ b/tests/test_git_colocated.rs @@ -158,8 +158,8 @@ fn test_git_colocated_rebase_on_import() { git_repo.branch("master", &commit1, true).unwrap(); git_repo.set_head("refs/heads/master").unwrap(); insta::assert_snapshot!(get_log_output(&test_env, &workspace_root), @r###" - @ 840303b127545e55dfa5858a97555acf54a80513 - o f0f3ab56bfa927e3a65c2ac9a513693d438e271b master + @ 7f96185cfbe36341d0f9a86ebfaeab67a5922c7e + o 4bcbeaba9a4b309c5f45a8807fbf5499b9714315 master o 0000000000000000000000000000000000000000 "###); } @@ -173,8 +173,8 @@ fn test_git_colocated_branches() { test_env.jj_cmd_success(&workspace_root, &["new", "-m", "foo"]); test_env.jj_cmd_success(&workspace_root, &["new", "@-", "-m", "bar"]); insta::assert_snapshot!(get_log_output(&test_env, &workspace_root), @r###" - @ 086821b6c35f5fdf07da884b859a14dcf85b5e36 - | o 6c0e140886d181602ae7a8e1ac41bc3094842370 + @ 3560559274ab431feea00b7b7e0b9250ecce951f + | o 1e6f0b403ed2ff9713b5d6b1dc601e4804250cda |/ o 230dd059e1b059aefc0da06a2e5a7dbf22362f22 master o 0000000000000000000000000000000000000000 @@ -185,7 +185,7 @@ fn test_git_colocated_branches() { test_env.jj_cmd_success(&workspace_root, &["branch", "set", "master"]); insta::assert_snapshot!( git_repo.find_reference("refs/heads/master").unwrap().target().unwrap().to_string(), - @"086821b6c35f5fdf07da884b859a14dcf85b5e36" + @"3560559274ab431feea00b7b7e0b9250ecce951f" ); insta::assert_snapshot!( git_repo.head().unwrap().target().unwrap().to_string(), @@ -196,7 +196,7 @@ fn test_git_colocated_branches() { git_repo .reference( "refs/heads/master", - Oid::from_str("6c0e140886d181602ae7a8e1ac41bc3094842370").unwrap(), + Oid::from_str("1e6f0b403ed2ff9713b5d6b1dc601e4804250cda").unwrap(), true, "test", ) @@ -204,7 +204,7 @@ fn test_git_colocated_branches() { insta::assert_snapshot!(get_log_output(&test_env, &workspace_root), @r###" Working copy now at: eb08b363bb5e (no description set) @ eb08b363bb5ef8ee549314260488980d7bbe8f63 - | o 6c0e140886d181602ae7a8e1ac41bc3094842370 master + | o 1e6f0b403ed2ff9713b5d6b1dc601e4804250cda master |/ o 230dd059e1b059aefc0da06a2e5a7dbf22362f22 o 0000000000000000000000000000000000000000 diff --git a/tests/test_git_push.rs b/tests/test_git_push.rs index ca7ba4984..9aa875a7b 100644 --- a/tests/test_git_push.rs +++ b/tests/test_git_push.rs @@ -73,32 +73,32 @@ fn test_git_push_current_branch() { // Check the setup let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list"]); insta::assert_snapshot!(stdout, @r###" - branch1: 73650434e2af modified branch1 commit - @origin (ahead by 1 commits, behind by 1 commits): 828a683493c6 description 1 - branch2: a7ba797894a9 foo - @origin (behind by 1 commits): 752dad8b1718 description 2 - my-branch: a7ba797894a9 foo + branch1: 19e00bf64429 modified branch1 commit + @origin (ahead by 1 commits, behind by 1 commits): 45a3aa29e907 description 1 + branch2: 10ee3363b259 foo + @origin (behind by 1 commits): 8476341eb395 description 2 + my-branch: 10ee3363b259 foo "###); // First dry-run. `branch1` should not get pushed. let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--dry-run"]); insta::assert_snapshot!(stdout, @r###" Branch changes to push to origin: - Move branch branch2 from 752dad8b1718 to a7ba797894a9 - Add branch my-branch to a7ba797894a9 + Move branch branch2 from 8476341eb395 to 10ee3363b259 + Add branch my-branch to 10ee3363b259 Dry-run requested, not pushing. "###); let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @r###" Branch changes to push to origin: - Move branch branch2 from 752dad8b1718 to a7ba797894a9 - Add branch my-branch to a7ba797894a9 + Move branch branch2 from 8476341eb395 to 10ee3363b259 + Add branch my-branch to 10ee3363b259 "###); let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list"]); insta::assert_snapshot!(stdout, @r###" - branch1: 73650434e2af modified branch1 commit - @origin (ahead by 1 commits, behind by 1 commits): 828a683493c6 description 1 - branch2: a7ba797894a9 foo - my-branch: a7ba797894a9 foo + branch1: 19e00bf64429 modified branch1 commit + @origin (ahead by 1 commits, behind by 1 commits): 45a3aa29e907 description 1 + branch2: 10ee3363b259 foo + my-branch: 10ee3363b259 foo "###); } @@ -114,7 +114,7 @@ fn test_git_push_parent_branch() { let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--dry-run"]); insta::assert_snapshot!(stdout, @r###" Branch changes to push to origin: - Force branch branch1 from 828a683493c6 to 83da0acb6a5a + Force branch branch1 from 45a3aa29e907 to d47326d59ee1 Dry-run requested, not pushing. "###); } @@ -143,18 +143,18 @@ fn test_git_push_multiple() { let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list"]); insta::assert_snapshot!(stdout, @r###" branch1 (deleted) - @origin: 828a683493c6 description 1 - branch2: afc3e612e744 foo - @origin (ahead by 1 commits, behind by 1 commits): 752dad8b1718 description 2 - my-branch: afc3e612e744 foo + @origin: 45a3aa29e907 description 1 + branch2: 15dcdaa4f12f foo + @origin (ahead by 1 commits, behind by 1 commits): 8476341eb395 description 2 + my-branch: 15dcdaa4f12f foo "###); // First dry-run let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--all", "--dry-run"]); insta::assert_snapshot!(stdout, @r###" Branch changes to push to origin: - Delete branch branch1 from 828a683493c6 - Force branch branch2 from 752dad8b1718 to afc3e612e744 - Add branch my-branch to afc3e612e744 + Delete branch branch1 from 45a3aa29e907 + Force branch branch2 from 8476341eb395 to 15dcdaa4f12f + Add branch my-branch to 15dcdaa4f12f Dry-run requested, not pushing. "###); // Dry run requesting two specific branches @@ -164,8 +164,8 @@ fn test_git_push_multiple() { ); insta::assert_snapshot!(stdout, @r###" Branch changes to push to origin: - Delete branch branch1 from 828a683493c6 - Add branch my-branch to afc3e612e744 + Delete branch branch1 from 45a3aa29e907 + Add branch my-branch to 15dcdaa4f12f Dry-run requested, not pushing. "###); // Dry run requesting two specific branches twice @@ -183,21 +183,21 @@ fn test_git_push_multiple() { ); insta::assert_snapshot!(stdout, @r###" Branch changes to push to origin: - Delete branch branch1 from 828a683493c6 - Add branch my-branch to afc3e612e744 + Delete branch branch1 from 45a3aa29e907 + Add branch my-branch to 15dcdaa4f12f Dry-run requested, not pushing. "###); let stdout = test_env.jj_cmd_success(&workspace_root, &["git", "push", "--all"]); insta::assert_snapshot!(stdout, @r###" Branch changes to push to origin: - Delete branch branch1 from 828a683493c6 - Force branch branch2 from 752dad8b1718 to afc3e612e744 - Add branch my-branch to afc3e612e744 + Delete branch branch1 from 45a3aa29e907 + Force branch branch2 from 8476341eb395 to 15dcdaa4f12f + Add branch my-branch to 15dcdaa4f12f "###); let stdout = test_env.jj_cmd_success(&workspace_root, &["branch", "list"]); insta::assert_snapshot!(stdout, @r###" - branch2: afc3e612e744 foo - my-branch: afc3e612e744 foo + branch2: 15dcdaa4f12f foo + my-branch: 15dcdaa4f12f foo "###); } @@ -219,7 +219,7 @@ fn test_git_push_changes() { insta::assert_snapshot!(replace_changeid(&stdout), @r###" Creating branch push- for revision @ Branch changes to push to origin: - Add branch push- to ccebc2439094 + Add branch push- to 28d7620ea63a "###); // test pushing two changes at once std::fs::write(workspace_root.join("file"), "modified2").unwrap(); @@ -230,8 +230,8 @@ fn test_git_push_changes() { insta::assert_snapshot!(replace_changeid(&stdout), @r###" Creating branch push- for revision @- Branch changes to push to origin: - Force branch push- from ccebc2439094 to 1624f122b2b1 - Add branch push- to 0a736fed65c0 + Force branch push- from 28d7620ea63a to 48d8c7948133 + Add branch push- to fa16a14170fb "###); // specifying the same change twice doesn't break things std::fs::write(workspace_root.join("file"), "modified3").unwrap(); @@ -241,7 +241,7 @@ fn test_git_push_changes() { ); insta::assert_snapshot!(replace_changeid(&stdout), @r###" Branch changes to push to origin: - Force branch push- from 1624f122b2b1 to bae35833f32d + Force branch push- from 48d8c7948133 to b5f030322b1d "###); } @@ -268,7 +268,7 @@ fn test_git_push_conflict() { test_env.jj_cmd_success(&workspace_root, &["describe", "-m", "third"]); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--all"]); insta::assert_snapshot!(stderr, @r###" - Error: Won't push commit 139ce31b3772 since it has conflicts + Error: Won't push commit 3a1497bff04c since it has conflicts "###); } @@ -301,14 +301,14 @@ fn test_git_push_missing_author() { &["git", "push", "--branch", "missing-name"], ); insta::assert_snapshot!(stderr, @r###" - Error: Won't push commit 83a72618d57e since it has no author and/or committer set + Error: Won't push commit 574dffd73428 since it has no author and/or committer set "###); run_without_var("JJ_EMAIL", &["checkout", "root", "-m=initial"]); run_without_var("JJ_EMAIL", &["branch", "create", "missing-email"]); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=missing-email"]); insta::assert_snapshot!(stderr, @r###" - Error: Won't push commit 0ed7ef529ef4 since it has no author and/or committer set + Error: Won't push commit e6c50f13f197 since it has no author and/or committer set "###); } @@ -327,7 +327,7 @@ fn test_git_push_missing_committer() { let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=missing-name"]); insta::assert_snapshot!(stderr, @r###" - Error: Won't push commit 3925a63f25e3 since it has no author and/or committer set + Error: Won't push commit e009726caa4a since it has no author and/or committer set "###); test_env.jj_cmd_success(&workspace_root, &["checkout", "root"]); test_env.jj_cmd_success(&workspace_root, &["branch", "create", "missing-email"]); @@ -335,7 +335,7 @@ fn test_git_push_missing_committer() { let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--branch=missing-email"]); insta::assert_snapshot!(stderr, @r###" - Error: Won't push commit 6c08d8150d73 since it has no author and/or committer set + Error: Won't push commit 27ec5f0793e6 since it has no author and/or committer set "###); // Test message when there are multiple reasons (missing committer and diff --git a/tests/test_move_command.rs b/tests/test_move_command.rs index dceb1c227..8d55d7617 100644 --- a/tests/test_move_command.rs +++ b/tests/test_move_command.rs @@ -371,8 +371,10 @@ fn test_move_description() { JJ: Enter a description for the combined commit. JJ: Description from the destination commit: destination + JJ: Description from the source commit: source + JJ: Lines starting with "JJ: " (like this one) will be removed. "#, ) @@ -380,6 +382,7 @@ JJ: Lines starting with "JJ: " (like this one) will be removed. test_env.jj_cmd_success(&repo_path, &["move", "--to", "@-"]); insta::assert_snapshot!(get_description(&test_env, &repo_path, "@-"), @r###" destination + source "###); diff --git a/tests/test_new_command.rs b/tests/test_new_command.rs index fb08c5950..6389dde47 100644 --- a/tests/test_new_command.rs +++ b/tests/test_new_command.rs @@ -28,17 +28,17 @@ fn test_new() { test_env.jj_cmd_success(&repo_path, &["new", "-m", "a new commit"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 88436dbcdbedc2b8a6ebd0687981906d09ccc68f a new commit - o 51e9c5819117991e4a6dc5a4a744283fc74f0746 add a file + @ 4f2d6e0a3482a6a34e4856a4a63869c0df109e79 a new commit + o 5d5c60b2aa96b8dbf55710656c50285c66cdcd74 add a file o 0000000000000000000000000000000000000000 (no description set) "###); // Start a new change off of a specific commit (the root commit in this case). test_env.jj_cmd_success(&repo_path, &["new", "-m", "off of root", "root"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ d8c0a3e1570f1f5b08113a3427b3160900c3d48e off of root - | o 88436dbcdbedc2b8a6ebd0687981906d09ccc68f a new commit - | o 51e9c5819117991e4a6dc5a4a744283fc74f0746 add a file + @ 026537ddb96b801b9cb909985d5443aab44616c1 off of root + | o 4f2d6e0a3482a6a34e4856a4a63869c0df109e79 a new commit + | o 5d5c60b2aa96b8dbf55710656c50285c66cdcd74 add a file |/ o 0000000000000000000000000000000000000000 (no description set) "###); @@ -59,10 +59,10 @@ fn test_new_merge() { // Create a merge commit test_env.jj_cmd_success(&repo_path, &["new", "main", "@"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 5b37ef8ee8cd934dfe1e70adff66cd0679f5a573 (no description set) + @ 0c4e5b9b68ae0cbe7ce3c61042619513d09005bf (no description set) |\ - o | 99814c62bec5c13d2053435b3d6bbeb1900cb57e add file2 - | o fe37af248a068697c6dcd7ebd17f5aac2205e7cb add file1 + o | f399209d9dda06e8a25a0c8e9a0cde9f421ff35d add file2 + | o 38e8e2f6c92ffb954961fc391b515ff551b41636 add file1 |/ o 0000000000000000000000000000000000000000 (no description set) "###); @@ -75,10 +75,10 @@ fn test_new_merge() { test_env.jj_cmd_success(&repo_path, &["undo"]); test_env.jj_cmd_success(&repo_path, &["merge", "main", "@"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ c34d60aa33225c2080da52faa39980efe944bddd (no description set) + @ 200ed1a14c8acf09783dafefe5bebf2ff58f12fd (no description set) |\ - o | 99814c62bec5c13d2053435b3d6bbeb1900cb57e add file2 - | o fe37af248a068697c6dcd7ebd17f5aac2205e7cb add file1 + o | f399209d9dda06e8a25a0c8e9a0cde9f421ff35d add file2 + | o 38e8e2f6c92ffb954961fc391b515ff551b41636 add file1 |/ o 0000000000000000000000000000000000000000 (no description set) "###); @@ -94,9 +94,9 @@ fn test_new_merge() { "###); // merge with non-unique revisions - let stderr = test_env.jj_cmd_failure(&repo_path, &["new", "@", "c34d"]); + let stderr = test_env.jj_cmd_failure(&repo_path, &["new", "@", "200e"]); insta::assert_snapshot!(stderr, @r###" - Error: Revset "@" and "c34d" resolved to the same revision c34d60aa3322 + Error: Revset "@" and "200e" resolved to the same revision 200ed1a14c8a "###); // merge with root diff --git a/tests/test_obslog_command.rs b/tests/test_obslog_command.rs index 0215ca035..d9f2727d2 100644 --- a/tests/test_obslog_command.rs +++ b/tests/test_obslog_command.rs @@ -34,13 +34,13 @@ fn test_obslog_with_or_without_diff() { let stdout = get_log_output(&test_env, &repo_path, &["obslog"]); insta::assert_snapshot!(stdout, @r###" - @ test.user@example.com 2001-02-03 04:05:10.000 +07:00 1daafc17fefb + @ test.user@example.com 2001-02-03 04:05:10.000 +07:00 66b42ad36073 | my description - o test.user@example.com 2001-02-03 04:05:09.000 +07:00 813918f7b4e6 conflict + o test.user@example.com 2001-02-03 04:05:09.000 +07:00 af536e5af67e conflict | my description - o test.user@example.com 2001-02-03 04:05:09.000 +07:00 8f02f5470c55 + o test.user@example.com 2001-02-03 04:05:09.000 +07:00 6fbba7bcb590 | my description - o test.user@example.com 2001-02-03 04:05:08.000 +07:00 c8ceb219336b + o test.user@example.com 2001-02-03 04:05:08.000 +07:00 eac0d0dae082 my description "###); @@ -48,43 +48,43 @@ fn test_obslog_with_or_without_diff() { // (even even though it resulted in a conflict). let stdout = get_log_output(&test_env, &repo_path, &["obslog", "-p"]); insta::assert_snapshot!(stdout, @r###" - @ test.user@example.com 2001-02-03 04:05:10.000 +07:00 1daafc17fefb + @ test.user@example.com 2001-02-03 04:05:10.000 +07:00 66b42ad36073 | my description | Resolved conflict in file1: | 1 1: <<<<<<>>>>>> - o test.user@example.com 2001-02-03 04:05:09.000 +07:00 813918f7b4e6 conflict + o test.user@example.com 2001-02-03 04:05:09.000 +07:00 af536e5af67e conflict | my description - o test.user@example.com 2001-02-03 04:05:09.000 +07:00 8f02f5470c55 + o test.user@example.com 2001-02-03 04:05:09.000 +07:00 6fbba7bcb590 | my description | Modified regular file file1: | 1 1: foo | 2: bar | Added regular file file2: | 1: foo - o test.user@example.com 2001-02-03 04:05:08.000 +07:00 c8ceb219336b + o test.user@example.com 2001-02-03 04:05:08.000 +07:00 eac0d0dae082 my description "###); // Test `--no-graph` let stdout = get_log_output(&test_env, &repo_path, &["obslog", "--no-graph"]); insta::assert_snapshot!(stdout, @r###" - test.user@example.com 2001-02-03 04:05:10.000 +07:00 1daafc17fefb + test.user@example.com 2001-02-03 04:05:10.000 +07:00 66b42ad36073 my description - test.user@example.com 2001-02-03 04:05:09.000 +07:00 813918f7b4e6 conflict + test.user@example.com 2001-02-03 04:05:09.000 +07:00 af536e5af67e conflict my description - test.user@example.com 2001-02-03 04:05:09.000 +07:00 8f02f5470c55 + test.user@example.com 2001-02-03 04:05:09.000 +07:00 6fbba7bcb590 my description - test.user@example.com 2001-02-03 04:05:08.000 +07:00 c8ceb219336b + test.user@example.com 2001-02-03 04:05:08.000 +07:00 eac0d0dae082 my description "###); // Test `--git` format, and that it implies `-p` let stdout = get_log_output(&test_env, &repo_path, &["obslog", "--no-graph", "--git"]); insta::assert_snapshot!(stdout, @r###" - test.user@example.com 2001-02-03 04:05:10.000 +07:00 1daafc17fefb + test.user@example.com 2001-02-03 04:05:10.000 +07:00 66b42ad36073 my description diff --git a/file1 b/file1 index e155302a24...2ab19ae607 100644 @@ -96,9 +96,9 @@ fn test_obslog_with_or_without_diff() { -+bar ->>>>>>> +resolved - test.user@example.com 2001-02-03 04:05:09.000 +07:00 813918f7b4e6 conflict + test.user@example.com 2001-02-03 04:05:09.000 +07:00 af536e5af67e conflict my description - test.user@example.com 2001-02-03 04:05:09.000 +07:00 8f02f5470c55 + test.user@example.com 2001-02-03 04:05:09.000 +07:00 6fbba7bcb590 my description diff --git a/file1 b/file1 index 257cc5642c...3bd1f0e297 100644 @@ -114,7 +114,7 @@ fn test_obslog_with_or_without_diff() { +++ b/file2 @@ -1,0 +1,1 @@ +foo - test.user@example.com 2001-02-03 04:05:08.000 +07:00 c8ceb219336b + test.user@example.com 2001-02-03 04:05:08.000 +07:00 eac0d0dae082 my description "###); } @@ -141,20 +141,20 @@ fn test_obslog_squash() { | | Modified regular file file1: | | 1 1: foo | | 2: bar - o | test.user@example.com 2001-02-03 04:05:09.000 +07:00 803a7299cb1a + o | test.user@example.com 2001-02-03 04:05:09.000 +07:00 9764e503e1a9 | | first | | Added regular file file1: | | 1: foo - o | test.user@example.com 2001-02-03 04:05:08.000 +07:00 85a1e2839620 + o | test.user@example.com 2001-02-03 04:05:08.000 +07:00 69542c1984c1 | | first o | test.user@example.com 2001-02-03 04:05:07.000 +07:00 230dd059e1b0 / (no description set) - o test.user@example.com 2001-02-03 04:05:10.000 +07:00 69231a40d60d + o test.user@example.com 2001-02-03 04:05:10.000 +07:00 f09a38899f2b | second | Modified regular file file1: | 1 1: foo | 2: bar - o test.user@example.com 2001-02-03 04:05:09.000 +07:00 b567edda97ab + o test.user@example.com 2001-02-03 04:05:09.000 +07:00 579965369703 second "###); } diff --git a/tests/test_operations.rs b/tests/test_operations.rs index 0c8151693..abc8e6a71 100644 --- a/tests/test_operations.rs +++ b/tests/test_operations.rs @@ -27,7 +27,7 @@ fn test_op_log() { let stdout = test_env.jj_cmd_success(&repo_path, &["op", "log"]); insta::assert_snapshot!(&stdout, @r###" - @ 29c6436f392b test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00 + @ 45108169c0f8 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00 | describe commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22 | args: jj describe -m 'description 0' o a99a3fd5c51e test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00 @@ -48,7 +48,7 @@ fn test_op_log() { "###); // "@" resolves to the head operation insta::assert_snapshot!(get_log_output(&test_env, &repo_path, "@"), @r###" - @ 335e69215d687b88eb3e4a83d51dcba183c43e24 + @ bc8f18aa6f396a93572811632313cbb5625d475d o 0000000000000000000000000000000000000000 "###); // "@-" resolves to the parent of the head operation diff --git a/tests/test_rebase_command.rs b/tests/test_rebase_command.rs index 3477c2d08..73f8ab462 100644 --- a/tests/test_rebase_command.rs +++ b/tests/test_rebase_command.rs @@ -75,13 +75,13 @@ fn test_rebase_invalid() { // Rebase onto descendant with -r let stderr = test_env.jj_cmd_failure(&repo_path, &["rebase", "-r", "a", "-d", "b"]); insta::assert_snapshot!(stderr, @r###" - Error: Cannot rebase 873140c1fed9 onto descendant ad05f5d1407c + Error: Cannot rebase 2443ea76b0b1 onto descendant 1394f625cbbd "###); // Rebase onto descendant with -s let stderr = test_env.jj_cmd_failure(&repo_path, &["rebase", "-s", "a", "-d", "b"]); insta::assert_snapshot!(stderr, @r###" - Error: Cannot rebase 873140c1fed9 onto descendant ad05f5d1407c + Error: Cannot rebase 2443ea76b0b1 onto descendant 1394f625cbbd "###); } @@ -150,7 +150,7 @@ fn test_rebase_branch_with_merge() { let stdout = test_env.jj_cmd_success(&repo_path, &["rebase", "-b", "d", "-d", "b"]); insta::assert_snapshot!(stdout, @r###" Rebased 3 commits - Working copy now at: b2674fa494af e + Working copy now at: 391c91a7defa e Added 1 files, modified 0 files, removed 0 files "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -166,7 +166,7 @@ fn test_rebase_branch_with_merge() { let stdout = test_env.jj_cmd_success(&repo_path, &["rebase", "-d", "b"]); insta::assert_snapshot!(stdout, @r###" Rebased 3 commits - Working copy now at: fef1da569696 e + Working copy now at: 040ae3a6d358 e Added 1 files, modified 0 files, removed 0 files "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -209,7 +209,7 @@ fn test_rebase_single_revision() { let stdout = test_env.jj_cmd_success(&repo_path, &["rebase", "-r", "b", "-d", "a"]); insta::assert_snapshot!(stdout, @r###" Also rebased 2 descendant commits onto parent of rebased commit - Working copy now at: ed4d09bb181f d + Working copy now at: 7e15b97a447f d Added 0 files, modified 0 files, removed 1 files "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -227,7 +227,7 @@ fn test_rebase_single_revision() { let stdout = test_env.jj_cmd_success(&repo_path, &["rebase", "-r", "c", "-d", "root"]); insta::assert_snapshot!(stdout, @r###" Also rebased 1 descendant commits onto parent of rebased commit - Working copy now at: 59a16d87a26f d + Working copy now at: bf87078f4560 d Added 0 files, modified 0 files, removed 1 files "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -269,7 +269,7 @@ fn test_rebase_single_revision_merge_parent() { let stdout = test_env.jj_cmd_success(&repo_path, &["rebase", "-r", "c", "-d", "a"]); insta::assert_snapshot!(stdout, @r###" Also rebased 1 descendant commits onto parent of rebased commit - Working copy now at: a4fccbb7582d d + Working copy now at: c62d0789e7c7 d Added 0 files, modified 0 files, removed 1 files "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @@ -345,7 +345,7 @@ fn test_rebase_with_descendants() { let stdout = test_env.jj_cmd_success(&repo_path, &["rebase", "-s", "b", "-d", "a"]); insta::assert_snapshot!(stdout, @r###" Rebased 3 commits - Working copy now at: 9afba1135175 d + Working copy now at: 309336ffce22 d "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" @ d diff --git a/tests/test_squash_command.rs b/tests/test_squash_command.rs index 74fba0eb0..e6e426b5b 100644 --- a/tests/test_squash_command.rs +++ b/tests/test_squash_command.rs @@ -287,8 +287,10 @@ fn test_squash_description() { JJ: Enter a description for the combined commit. JJ: Description from the destination commit: destination + JJ: Description from the source commit: source + JJ: Lines starting with "JJ: " (like this one) will be removed. "#, ) @@ -296,6 +298,7 @@ JJ: Lines starting with "JJ: " (like this one) will be removed. test_env.jj_cmd_success(&repo_path, &["squash"]); insta::assert_snapshot!(get_description(&test_env, &repo_path, "@-"), @r###" destination + source "###); diff --git a/tests/test_status_command.rs b/tests/test_status_command.rs index 1f0a3d582..9d1214b8a 100644 --- a/tests/test_status_command.rs +++ b/tests/test_status_command.rs @@ -33,9 +33,9 @@ fn test_status_merge() { // to the auto-merged parents) let stdout = test_env.jj_cmd_success(&repo_path, &["status"]); insta::assert_snapshot!(stdout, @r###" - Parent commit: c4097d2ac7c9 left - Parent commit: 481d94cd6e34 right - Working copy : 92fb36a0639c (no description set) + Parent commit: 9ae48ddba058 left + Parent commit: 29b991e938dd right + Working copy : c965365c98d2 (no description set) The working copy is clean "###); } diff --git a/tests/test_templater.rs b/tests/test_templater.rs index 14021fe46..4f6f883f9 100644 --- a/tests/test_templater.rs +++ b/tests/test_templater.rs @@ -66,12 +66,12 @@ fn test_templater_branches() { &["log", "-T", r#"commit_id.short() " " branches"#], ); insta::assert_snapshot!(output, @r###" - o 48e0b6c42296 branch3? - | @ 092b2e0283a9 branch2* new-branch - | | o f4a739b1677f branch1* + o b1bb3766d584 branch3? + | @ a5b4d15489cc branch2* new-branch + | | o 21c33875443e branch1* | |/ |/| - | o 752dad8b1718 branch2@origin + | o 8476341eb395 branch2@origin |/ o 000000000000 "###); diff --git a/tests/test_unsquash_command.rs b/tests/test_unsquash_command.rs index c0c4fc191..b6022caad 100644 --- a/tests/test_unsquash_command.rs +++ b/tests/test_unsquash_command.rs @@ -86,7 +86,7 @@ fn test_unsquash() { test_env.jj_cmd_success(&repo_path, &["new", "-m", "merge", "c", "d"]); test_env.jj_cmd_success(&repo_path, &["branch", "create", "e"]); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 7789610d8ec6 e + @ 1f8f152ff48e e |\ o | 5658521e0f8b d | o 90fe0a96fc90 c @@ -105,10 +105,10 @@ fn test_unsquash() { std::fs::write(repo_path.join("file1"), "e\n").unwrap(); let stdout = test_env.jj_cmd_success(&repo_path, &["unsquash"]); insta::assert_snapshot!(stdout, @r###" - Working copy now at: 0aabd9784f4d merge + Working copy now at: 3217340cb761 merge "###); insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" - @ 0aabd9784f4d + @ 3217340cb761 |\ o | 5658521e0f8b d e? | o 90fe0a96fc90 c e? @@ -253,8 +253,10 @@ fn test_unsquash_description() { JJ: Enter a description for the combined commit. JJ: Description from the destination commit: destination + JJ: Description from the source commit: source + JJ: Lines starting with "JJ: " (like this one) will be removed. "#, ) @@ -262,6 +264,7 @@ JJ: Lines starting with "JJ: " (like this one) will be removed. test_env.jj_cmd_success(&repo_path, &["unsquash"]); insta::assert_snapshot!(get_description(&test_env, &repo_path, "@"), @r###" destination + source "###); diff --git a/tests/test_workspaces.rs b/tests/test_workspaces.rs index 62c8d30b5..b4b753ff7 100644 --- a/tests/test_workspaces.rs +++ b/tests/test_workspaces.rs @@ -31,7 +31,7 @@ fn test_workspaces_add_second_workspace() { let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]); insta::assert_snapshot!(stdout, @r###" - default: 988d8c1dca7e (no description set) + default: e0e6d5672858 (no description set) "###); let stdout = test_env.jj_cmd_success( @@ -40,32 +40,32 @@ fn test_workspaces_add_second_workspace() { ); insta::assert_snapshot!(stdout.replace('\\', "/"), @r###" Created workspace in "../secondary" - Working copy now at: 8ac248e0c8d2 (no description set) + Working copy now at: 397eac932ad3 (no description set) Added 1 files, modified 0 files, removed 0 files "###); // Can see the checkout in each workspace in the log output. The "@" node in the // graph indicates the current workspace's checkout. insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###" - o 8ac248e0c8d2d1865fe3679296e329c0137b1a31 second@ - | @ 988d8c1dca7e0944210ccc33584a6a42cd2962d4 default@ + o 397eac932ad3c349b2659fd2eb035a4dd3da4193 second@ + | @ e0e6d5672858dc9a57ec5b772b7c4f3270ed0223 default@ |/ - o 2062e7d6f1f46b4fe1453040d691931e77a88f7c + o 7d308bc9d934c53c6cc52935192e2d6ac5d78cfd o 0000000000000000000000000000000000000000 "###); insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r###" - @ 8ac248e0c8d2d1865fe3679296e329c0137b1a31 second@ - | o 988d8c1dca7e0944210ccc33584a6a42cd2962d4 default@ + @ 397eac932ad3c349b2659fd2eb035a4dd3da4193 second@ + | o e0e6d5672858dc9a57ec5b772b7c4f3270ed0223 default@ |/ - o 2062e7d6f1f46b4fe1453040d691931e77a88f7c + o 7d308bc9d934c53c6cc52935192e2d6ac5d78cfd o 0000000000000000000000000000000000000000 "###); // Both workspaces show up when we list them let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]); insta::assert_snapshot!(stdout, @r###" - default: 988d8c1dca7e (no description set) - second: 8ac248e0c8d2 (no description set) + default: e0e6d5672858 (no description set) + second: 397eac932ad3 (no description set) "###); }