Repository: commitizen-tools/commitizen (Python)

Issue:
Can you add the commit sha1 in the changelog command?
### Description

I would like to be able to customize the changelog template adding the sha1:

```

{% for change in changes %}
{% if change.scope %}
- *{{ change.scope }}*: {{ change.message }} ({{ change.sha1 }})
{% elif change.message %}
- {{ change.message }} ({{ change.sha1 }})
{% endif %}
{% endfor %}
```

Thanks

### Possible Solution

Add the sha1 in the "Change" object. Maybe author as well.

### Additional context

_No response_

### Additional context

_No response_


Discussion:
Hi 👋🏼 

I created a pull request (#1013) to add this, but given it's not without impact (increase memory usage on changelog generation), it needs to be discussed I think.

Anyway, this is already possible with the following [`changelog_message_builder_hook`](https://commitizen-tools.github.io/commitizen/customization/#custom-changelog-generator)

```python
def changelog_message_builder_hook(
        self, parsed_message: dict, commit: git.GitCommit
    ) -> dict | list | None:
		parsed_message.update(
			sha1=commit.rev,
            author=commit.author,
        	author_email=commit.author_email,
		)
        return parsed_message
```


Hello Thanks !



Patch:
diff --git a/commitizen/changelog.py b/commitizen/changelog.py
index 5c713af0e6..3f048a420e 100644
--- a/commitizen/changelog.py
+++ b/commitizen/changelog.py
@@ -188,7 +188,12 @@ def process_commit_message(
     changes: dict[str | None, list],
     change_type_map: dict[str, str] | None = None,
 ):
-    message: dict = parsed.groupdict()
+    message: dict = {
+        "sha1": commit.rev,
+        "author": commit.author,
+        "author_email": commit.author_email,
+        **parsed.groupdict(),
+    }
 
     if processed := hook(message, commit) if hook else message:
         messages = [processed] if isinstance(processed, dict) else processed
diff --git a/docs/customization.md b/docs/customization.md
index 7d352f0313..a36d85df99 100644
--- a/docs/customization.md
+++ b/docs/customization.md
@@ -500,6 +500,9 @@ Each `Change` has the following fields:
 | ---- | ---- | ----------- |
 | scope | `str | None` | An optional scope |
 | message | `str` | The commit message body |
+| sha1 | `str` | The commit `sha1` |
+| author | `str` | The commit author name |
+| author_email | `str` | The commit author email |
 
 !!! Note
     The field values depend on the customization class and/or the settings you provide


Test patch:
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index 7944f66dd8..93cdf77015 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -1083,10 +1083,24 @@ def test_generate_tree_from_commits(gitcommits, tags, merge_prereleases):
     tree = changelog.generate_tree_from_commits(
         gitcommits, tags, parser, changelog_pattern, merge_prerelease=merge_prereleases
     )
-    if merge_prereleases:
-        assert tuple(tree) == COMMITS_TREE_AFTER_MERGED_PRERELEASES
-    else:
-        assert tuple(tree) == COMMITS_TREE
+    expected = (
+        COMMITS_TREE_AFTER_MERGED_PRERELEASES if merge_prereleases else COMMITS_TREE
+    )
+
+    for release, expected_release in zip(tree, expected):
+        assert release["version"] == expected_release["version"]
+        assert release["date"] == expected_release["date"]
+        assert release["changes"].keys() == expected_release["changes"].keys()
+        for change_type in release["changes"]:
+            changes = release["changes"][change_type]
+            expected_changes = expected_release["changes"][change_type]
+            for change, expected_change in zip(changes, expected_changes):
+                assert change["scope"] == expected_change["scope"]
+                assert change["breaking"] == expected_change["breaking"]
+                assert change["message"] == expected_change["message"]
+                assert change["author"] == "Commitizen"
+                assert change["author_email"] in "author@cz.dev"
+                assert "sha1" in change
 
 
 def test_generate_tree_from_commits_with_no_commits(tags):