diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d3bc2caa3..51f6f2fdc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). * `jj squash`: the `-k` flag can be used as a shorthand for `--keep-emptied`. +* CommitId / ChangeId template types now support `.normal_hex()`. + ### Fixed bugs * Fixed panic when parsing invalid conflict markers of a particular form. diff --git a/cli/src/commit_templater.rs b/cli/src/commit_templater.rs index acf9d580a6..4b4a7f86c6 100644 --- a/cli/src/commit_templater.rs +++ b/cli/src/commit_templater.rs @@ -1225,6 +1225,21 @@ fn builtin_commit_or_change_id_methods<'repo>( // Not using maplit::hashmap!{} or custom declarative macro here because // code completion inside macro is quite restricted. let mut map = CommitTemplateBuildMethodFnMap::::new(); + map.insert( + "normal_hex", + |_language, _build_ctx, self_property, function| { + function.expect_no_arguments()?; + Ok(L::wrap_string(self_property.map(|id| { + // Note: this is _not_ the same as id.hex() for ChangeId, which + // returns the "reverse" hex (z-k), instead of the "forward" / + // normal hex (0-9a-f) we want here. + match id { + CommitOrChangeId::Commit(id) => id.hex(), + CommitOrChangeId::Change(id) => id.hex(), + } + }))) + }, + ); map.insert("short", |language, build_ctx, self_property, function| { let ([], [len_node]) = function.expect_arguments()?; let len_property = len_node diff --git a/cli/tests/test_commit_template.rs b/cli/tests/test_commit_template.rs index 7d427149be..852f975d21 100644 --- a/cli/tests/test_commit_template.rs +++ b/cli/tests/test_commit_template.rs @@ -643,6 +643,56 @@ fn test_log_git_head() { "###); } +#[test] +fn test_log_commit_id_normal_hex() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); + let repo_path = test_env.env_root().join("repo"); + + test_env.jj_cmd_ok(&repo_path, &["new", "-m", "first"]); + test_env.jj_cmd_ok(&repo_path, &["new", "-m", "second"]); + + let stdout = test_env.jj_cmd_success( + &repo_path, + &[ + "log", + "-T", + r#"commit_id ++ ": " ++ commit_id.normal_hex()"#, + ], + ); + insta::assert_snapshot!(stdout, @r#" + @ 6572f22267c6f0f2bf7b8a37969ee5a7d54b8aae: 6572f22267c6f0f2bf7b8a37969ee5a7d54b8aae + ○ 222fa9f0b41347630a1371203b8aad3897d34e5f: 222fa9f0b41347630a1371203b8aad3897d34e5f + ○ 230dd059e1b059aefc0da06a2e5a7dbf22362f22: 230dd059e1b059aefc0da06a2e5a7dbf22362f22 + ◆ 0000000000000000000000000000000000000000: 0000000000000000000000000000000000000000 + "#); +} + +#[test] +fn test_log_change_id_normal_hex() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]); + let repo_path = test_env.env_root().join("repo"); + + test_env.jj_cmd_ok(&repo_path, &["new", "-m", "first"]); + test_env.jj_cmd_ok(&repo_path, &["new", "-m", "second"]); + + let stdout = test_env.jj_cmd_success( + &repo_path, + &[ + "log", + "-T", + r#"change_id ++ ": " ++ change_id.normal_hex()"#, + ], + ); + insta::assert_snapshot!(stdout, @r#" + @ kkmpptxzrspxrzommnulwmwkkqwworpl: ffdaa62087a280bddc5e3d3ff933b8ae + ○ rlvkpnrzqnoowoytxnquwvuryrwnrmlp: 8e4fac809cbb3b162c953458183c8dea + ○ qpvuntsmwlqtpsluzzsnyyzlmlwvmlnu: 9a45c67d3e96a7e5007c110ede34dec5 + ◆ zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz: 00000000000000000000000000000000 + "#); +} + #[test] fn test_log_customize_short_id() { let test_env = TestEnvironment::default(); diff --git a/docs/templates.md b/docs/templates.md index 68f553e895..5fef4ea1fa 100644 --- a/docs/templates.md +++ b/docs/templates.md @@ -105,6 +105,8 @@ This type cannot be printed. The following methods are defined. The following methods are defined. +* `.normal_hex() -> String`: Normal hex representation (0-9a-f), useful for + ChangeId, whose canonical hex representation is "reversed" (z-k). * `.short([len: Integer]) -> String` * `.shortest([min_len: Integer]) -> ShortestIdPrefix`: Shortest unique prefix.