From 991a36d71b6151a740f161fa1e4789b66109b3cc Mon Sep 17 00:00:00 2001
From: Alejandro Martinez Ruiz <alex@flawedcode.org>
Date: Thu, 20 Mar 2025 14:25:47 +0100
Subject: [PATCH 1/3] feat(git): add parents' digests in commit information

---
 commitizen/git.py | 16 +++++++++++---
 tests/test_git.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/commitizen/git.py b/commitizen/git.py
index 7de8e1f1c..19ca46b6c 100644
--- a/commitizen/git.py
+++ b/commitizen/git.py
@@ -44,13 +44,20 @@ def __eq__(self, other) -> bool:
 
 class GitCommit(GitObject):
     def __init__(
-        self, rev, title, body: str = "", author: str = "", author_email: str = ""
+        self,
+        rev,
+        title,
+        body: str = "",
+        author: str = "",
+        author_email: str = "",
+        parents: list[str] | None = None,
     ):
         self.rev = rev.strip()
         self.title = title.strip()
         self.body = body.strip()
         self.author = author.strip()
         self.author_email = author_email.strip()
+        self.parents = parents or []
 
     @property
     def message(self):
@@ -137,7 +144,9 @@ def get_commits(
     for rev_and_commit in git_log_entries:
         if not rev_and_commit:
             continue
-        rev, title, author, author_email, *body_list = rev_and_commit.split("\n")
+        rev, parents, title, author, author_email, *body_list = rev_and_commit.split(
+            "\n"
+        )
         if rev_and_commit:
             git_commit = GitCommit(
                 rev=rev.strip(),
@@ -145,6 +154,7 @@ def get_commits(
                 body="\n".join(body_list).strip(),
                 author=author,
                 author_email=author_email,
+                parents=[p for p in parents.strip().split(" ") if p],
             )
             git_commits.append(git_commit)
     return git_commits
@@ -286,7 +296,7 @@ def smart_open(*args, **kargs):
 def _get_log_as_str_list(start: str | None, end: str, args: str) -> list[str]:
     """Get string representation of each log entry"""
     delimiter = "----------commit-delimiter----------"
-    log_format: str = "%H%n%s%n%an%n%ae%n%b"
+    log_format: str = "%H%n%P%n%s%n%an%n%ae%n%b"
     git_log_cmd = (
         f"git -c log.showSignature=False log --pretty={log_format}{delimiter} {args}"
     )
diff --git a/tests/test_git.py b/tests/test_git.py
index f929ba6a4..8b2fc2b86 100644
--- a/tests/test_git.py
+++ b/tests/test_git.py
@@ -132,11 +132,13 @@ def test_get_commits_author_and_email():
 def test_get_commits_without_email(mocker: MockFixture):
     raw_commit = (
         "a515bb8f71c403f6f7d1c17b9d8ebf2ce3959395\n"
+        "95bbfc703eb99cb49ba0d6ffd8469911303dbe63 12d3b4bdaa996ea7067a07660bb5df4772297bdd\n"
         "\n"
         "user name\n"
         "\n"
         "----------commit-delimiter----------\n"
         "12d3b4bdaa996ea7067a07660bb5df4772297bdd\n"
+        "de33bc5070de19600f2f00262b3c15efea762408\n"
         "feat(users): add username\n"
         "user name\n"
         "\n"
@@ -159,16 +161,19 @@ def test_get_commits_without_email(mocker: MockFixture):
 def test_get_commits_without_breakline_in_each_commit(mocker: MockFixture):
     raw_commit = (
         "ae9ba6fc5526cf478f52ef901418d85505109744\n"
+        "ff2f56ca844de72a9d59590831087bf5a97bac84\n"
         "bump: version 2.13.0 → 2.14.0\n"
         "GitHub Action\n"
         "action@github.com\n"
         "----------commit-delimiter----------\n"
         "ff2f56ca844de72a9d59590831087bf5a97bac84\n"
+        "b4dc83284dc8c9729032a774a037df1d1f2397d5 20a54bf1b82cd7b573351db4d1e8814dd0be205d\n"
         "Merge pull request #332 from cliles/feature/271-redux\n"
         "User\n"
         "user@email.com\n"
         "Feature/271 redux----------commit-delimiter----------\n"
         "20a54bf1b82cd7b573351db4d1e8814dd0be205d\n"
+        "658f38c3fe832cdab63ed4fb1f7b3a0969a583be\n"
         "feat(#271): enable creation of annotated tags when bumping\n"
         "User 2\n"
         "user@email.edu\n"
@@ -193,6 +198,55 @@ def test_get_commits_without_breakline_in_each_commit(mocker: MockFixture):
     )
 
 
+def test_get_commits_with_and_without_parents(mocker: MockFixture):
+    raw_commit = (
+        "4206e661bacf9643373255965f34bbdb382cb2b9\n"
+        "ae9ba6fc5526cf478f52ef901418d85505109744 bf8479e7aa1a5b9d2f491b79e3a4d4015519903e\n"
+        "Merge pull request from someone\n"
+        "Maintainer\n"
+        "maintainer@email.com\n"
+        "This is a much needed feature----------commit-delimiter----------\n"
+        "ae9ba6fc5526cf478f52ef901418d85505109744\n"
+        "ff2f56ca844de72a9d59590831087bf5a97bac84\n"
+        "Release 0.1.0\n"
+        "GitHub Action\n"
+        "action@github.com\n"
+        "----------commit-delimiter----------\n"
+        "ff2f56ca844de72a9d59590831087bf5a97bac84\n"
+        "\n"
+        "Initial commit\n"
+        "User\n"
+        "user@email.com\n"
+        "----------commit-delimiter----------\n"
+    )
+    mocker.patch("commitizen.cmd.run", return_value=FakeCommand(out=raw_commit))
+
+    commits = git.get_commits()
+
+    assert commits[0].author == "Maintainer"
+    assert commits[1].author == "GitHub Action"
+    assert commits[2].author == "User"
+
+    assert commits[0].author_email == "maintainer@email.com"
+    assert commits[1].author_email == "action@github.com"
+    assert commits[2].author_email == "user@email.com"
+
+    assert commits[0].title == "Merge pull request from someone"
+    assert commits[1].title == "Release 0.1.0"
+    assert commits[2].title == "Initial commit"
+
+    assert commits[0].body == "This is a much needed feature"
+    assert commits[1].body == ""
+    assert commits[2].body == ""
+
+    assert commits[0].parents == [
+        "ae9ba6fc5526cf478f52ef901418d85505109744",
+        "bf8479e7aa1a5b9d2f491b79e3a4d4015519903e",
+    ]
+    assert commits[1].parents == ["ff2f56ca844de72a9d59590831087bf5a97bac84"]
+    assert commits[2].parents == []
+
+
 def test_get_commits_with_signature():
     config_file = ".git/config"
     config_backup = ".git/config.bak"

From 7f3337a3ad42ac72ff59a87d5dfb37752f9d9bdc Mon Sep 17 00:00:00 2001
From: Alejandro Martinez Ruiz <alex@flawedcode.org>
Date: Thu, 20 Mar 2025 14:25:54 +0100
Subject: [PATCH 2/3] feat(changelog): expose commit parents' digests when
 processing commits

COMMIT_DATA in test_changelog.py had to be type annotated to avoid an
issue with mypy linting when creating a GitCommit where the tool would
expect the wrong type for the arguments.
---
 commitizen/changelog.py |  1 +
 tests/test_changelog.py | 75 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/commitizen/changelog.py b/commitizen/changelog.py
index 95bf21d6f..704efe607 100644
--- a/commitizen/changelog.py
+++ b/commitizen/changelog.py
@@ -172,6 +172,7 @@ def process_commit_message(
 ):
     message: dict = {
         "sha1": commit.rev,
+        "parents": commit.parents,
         "author": commit.author,
         "author_email": commit.author_email,
         **parsed.groupdict(),
diff --git a/tests/test_changelog.py b/tests/test_changelog.py
index accbf5d33..df42b8226 100644
--- a/tests/test_changelog.py
+++ b/tests/test_changelog.py
@@ -1,7 +1,7 @@
 import re
 from dataclasses import dataclass
 from pathlib import Path
-from typing import Optional
+from typing import Any, Optional
 
 import pytest
 from jinja2 import FileSystemLoader
@@ -14,9 +14,10 @@
 from commitizen.exceptions import InvalidConfigurationError
 from commitizen.version_schemes import Pep440
 
-COMMITS_DATA = [
+COMMITS_DATA: list[dict[str, Any]] = [
     {
         "rev": "141ee441c9c9da0809c554103a558eb17c30ed17",
+        "parents": ["6c4948501031b7d6405b54b21d3d635827f9421b"],
         "title": "bump: version 1.1.1 → 1.2.0",
         "body": "",
         "author": "Commitizen",
@@ -24,6 +25,7 @@
     },
     {
         "rev": "6c4948501031b7d6405b54b21d3d635827f9421b",
+        "parents": ["ddd220ad515502200fe2dde443614c1075d26238"],
         "title": "docs: how to create custom bumps",
         "body": "",
         "author": "Commitizen",
@@ -31,6 +33,7 @@
     },
     {
         "rev": "ddd220ad515502200fe2dde443614c1075d26238",
+        "parents": ["ad17acff2e3a2e141cbc3c6efd7705e4e6de9bfc"],
         "title": "feat: custom cz plugins now support bumping version",
         "body": "",
         "author": "Commitizen",
@@ -38,6 +41,7 @@
     },
     {
         "rev": "ad17acff2e3a2e141cbc3c6efd7705e4e6de9bfc",
+        "parents": ["56c8a8da84e42b526bcbe130bd194306f7c7e813"],
         "title": "docs: added bump gif",
         "body": "",
         "author": "Commitizen",
@@ -45,6 +49,7 @@
     },
     {
         "rev": "56c8a8da84e42b526bcbe130bd194306f7c7e813",
+        "parents": ["74c6134b1b2e6bb8b07ed53410faabe99b204f36"],
         "title": "bump: version 1.1.0 → 1.1.1",
         "body": "",
         "author": "Commitizen",
@@ -52,6 +57,7 @@
     },
     {
         "rev": "74c6134b1b2e6bb8b07ed53410faabe99b204f36",
+        "parents": ["cbc7b5f22c4e74deff4bc92d14e19bd93524711e"],
         "title": "refactor: changed stdout statements",
         "body": "",
         "author": "Commitizen",
@@ -59,6 +65,7 @@
     },
     {
         "rev": "cbc7b5f22c4e74deff4bc92d14e19bd93524711e",
+        "parents": ["1ba46f2a63cb9d6e7472eaece21528c8cd28b118"],
         "title": "fix(bump): commit message now fits better with semver",
         "body": "",
         "author": "Commitizen",
@@ -66,6 +73,7 @@
     },
     {
         "rev": "1ba46f2a63cb9d6e7472eaece21528c8cd28b118",
+        "parents": ["c35dbffd1bb98bb0b3d1593797e79d1c3366af8f"],
         "title": "fix: conventional commit 'breaking change' in body instead of title",
         "body": "closes #16",
         "author": "Commitizen",
@@ -73,6 +81,7 @@
     },
     {
         "rev": "c35dbffd1bb98bb0b3d1593797e79d1c3366af8f",
+        "parents": ["25313397a4ac3dc5b5c986017bee2a614399509d"],
         "title": "refactor(schema): command logic removed from commitizen base",
         "body": "",
         "author": "Commitizen",
@@ -80,6 +89,7 @@
     },
     {
         "rev": "25313397a4ac3dc5b5c986017bee2a614399509d",
+        "parents": ["d2f13ac41b4e48995b3b619d931c82451886e6ff"],
         "title": "refactor(info): command logic removed from commitizen base",
         "body": "",
         "author": "Commitizen",
@@ -87,6 +97,7 @@
     },
     {
         "rev": "d2f13ac41b4e48995b3b619d931c82451886e6ff",
+        "parents": ["d839e317e5b26671b010584ad8cc6bf362400fa1"],
         "title": "refactor(example): command logic removed from commitizen base",
         "body": "",
         "author": "Commitizen",
@@ -94,6 +105,7 @@
     },
     {
         "rev": "d839e317e5b26671b010584ad8cc6bf362400fa1",
+        "parents": ["12d0e65beda969f7983c444ceedc2a01584f4e08"],
         "title": "refactor(commit): moved most of the commit logic to the commit command",
         "body": "",
         "author": "Commitizen",
@@ -101,6 +113,7 @@
     },
     {
         "rev": "12d0e65beda969f7983c444ceedc2a01584f4e08",
+        "parents": ["fb4c85abe51c228e50773e424cbd885a8b6c610d"],
         "title": "docs(README): updated documentation url)",
         "body": "",
         "author": "Commitizen",
@@ -108,6 +121,7 @@
     },
     {
         "rev": "fb4c85abe51c228e50773e424cbd885a8b6c610d",
+        "parents": ["17efb44d2cd16f6621413691a543e467c7d2dda6"],
         "title": "docs: mkdocs documentation",
         "body": "",
         "author": "Commitizen",
@@ -115,6 +129,7 @@
     },
     {
         "rev": "17efb44d2cd16f6621413691a543e467c7d2dda6",
+        "parents": ["6012d9eecfce8163d75c8fff179788e9ad5347da"],
         "title": "Bump version 1.0.0 → 1.1.0",
         "body": "",
         "author": "Commitizen",
@@ -122,6 +137,7 @@
     },
     {
         "rev": "6012d9eecfce8163d75c8fff179788e9ad5347da",
+        "parents": ["0c7fb0ca0168864dfc55d83c210da57771a18319"],
         "title": "test: fixed issues with conf",
         "body": "",
         "author": "Commitizen",
@@ -129,6 +145,7 @@
     },
     {
         "rev": "0c7fb0ca0168864dfc55d83c210da57771a18319",
+        "parents": ["cb1dd2019d522644da5bdc2594dd6dee17122d7f"],
         "title": "docs(README): some new information about bump",
         "body": "",
         "author": "Commitizen",
@@ -136,6 +153,7 @@
     },
     {
         "rev": "cb1dd2019d522644da5bdc2594dd6dee17122d7f",
+        "parents": ["9c7450f85df6bf6be508e79abf00855a30c3c73c"],
         "title": "feat: new working bump command",
         "body": "",
         "author": "Commitizen",
@@ -143,6 +161,7 @@
     },
     {
         "rev": "9c7450f85df6bf6be508e79abf00855a30c3c73c",
+        "parents": ["9f3af3772baab167e3fd8775d37f041440184251"],
         "title": "feat: create version tag",
         "body": "",
         "author": "Commitizen",
@@ -150,6 +169,7 @@
     },
     {
         "rev": "9f3af3772baab167e3fd8775d37f041440184251",
+        "parents": ["b0d6a3defbfde14e676e7eb34946409297d0221b"],
         "title": "docs: added new changelog",
         "body": "",
         "author": "Commitizen",
@@ -157,6 +177,7 @@
     },
     {
         "rev": "b0d6a3defbfde14e676e7eb34946409297d0221b",
+        "parents": ["d630d07d912e420f0880551f3ac94e933f9d3beb"],
         "title": "feat: update given files with new version",
         "body": "",
         "author": "Commitizen",
@@ -164,6 +185,7 @@
     },
     {
         "rev": "d630d07d912e420f0880551f3ac94e933f9d3beb",
+        "parents": ["1792b8980c58787906dbe6836f93f31971b1ec2d"],
         "title": "fix: removed all from commit",
         "body": "",
         "author": "Commitizen",
@@ -171,6 +193,7 @@
     },
     {
         "rev": "1792b8980c58787906dbe6836f93f31971b1ec2d",
+        "parents": ["52def1ea3555185ba4b936b463311949907e31ec"],
         "title": "feat(config): new set key, used to set version to cfg",
         "body": "",
         "author": "Commitizen",
@@ -178,6 +201,7 @@
     },
     {
         "rev": "52def1ea3555185ba4b936b463311949907e31ec",
+        "parents": ["3127e05077288a5e2b62893345590bf1096141b7"],
         "title": "feat: support for pyproject.toml",
         "body": "",
         "author": "Commitizen",
@@ -185,6 +209,7 @@
     },
     {
         "rev": "3127e05077288a5e2b62893345590bf1096141b7",
+        "parents": ["fd480ed90a80a6ffa540549408403d5b60d0e90c"],
         "title": "feat: first semantic version bump implementation",
         "body": "",
         "author": "Commitizen",
@@ -192,6 +217,7 @@
     },
     {
         "rev": "fd480ed90a80a6ffa540549408403d5b60d0e90c",
+        "parents": ["e4840a059731c0bf488381ffc77e989e85dd81ad"],
         "title": "fix: fix config file not working",
         "body": "",
         "author": "Commitizen",
@@ -199,6 +225,7 @@
     },
     {
         "rev": "e4840a059731c0bf488381ffc77e989e85dd81ad",
+        "parents": ["aa44a92d68014d0da98965c0c2cb8c07957d4362"],
         "title": "refactor: added commands folder, better integration with decli",
         "body": "",
         "author": "Commitizen",
@@ -206,6 +233,7 @@
     },
     {
         "rev": "aa44a92d68014d0da98965c0c2cb8c07957d4362",
+        "parents": ["58bb709765380dbd46b74ce6e8978515764eb955"],
         "title": "Bump version: 1.0.0b2 → 1.0.0",
         "body": "",
         "author": "Commitizen",
@@ -213,6 +241,7 @@
     },
     {
         "rev": "58bb709765380dbd46b74ce6e8978515764eb955",
+        "parents": ["97afb0bb48e72b6feca793091a8a23c706693257"],
         "title": "docs(README): new badges",
         "body": "",
         "author": "Commitizen",
@@ -220,6 +249,10 @@
     },
     {
         "rev": "97afb0bb48e72b6feca793091a8a23c706693257",
+        "parents": [
+            "9cecb9224aa7fa68d4afeac37eba2a25770ef251",
+            "e004a90b81ea5b374f118759bce5951202d03d69",
+        ],
         "title": "Merge pull request #10 from Woile/feat/decli",
         "body": "Feat/decli",
         "author": "Commitizen",
@@ -227,6 +260,7 @@
     },
     {
         "rev": "9cecb9224aa7fa68d4afeac37eba2a25770ef251",
+        "parents": ["f5781d1a2954d71c14ade2a6a1a95b91310b2577"],
         "title": "style: black to files",
         "body": "",
         "author": "Commitizen",
@@ -234,6 +268,7 @@
     },
     {
         "rev": "f5781d1a2954d71c14ade2a6a1a95b91310b2577",
+        "parents": ["80105fb3c6d45369bc0cbf787bd329fba603864c"],
         "title": "ci: added travis",
         "body": "",
         "author": "Commitizen",
@@ -241,6 +276,7 @@
     },
     {
         "rev": "80105fb3c6d45369bc0cbf787bd329fba603864c",
+        "parents": ["a96008496ffefb6b1dd9b251cb479eac6a0487f7"],
         "title": "refactor: removed delegator, added decli and many tests",
         "body": "BREAKING CHANGE: API is stable",
         "author": "Commitizen",
@@ -248,6 +284,7 @@
     },
     {
         "rev": "a96008496ffefb6b1dd9b251cb479eac6a0487f7",
+        "parents": ["aab33d13110f26604fb786878856ec0b9e5fc32b"],
         "title": "docs: updated test command",
         "body": "",
         "author": "Commitizen",
@@ -255,6 +292,7 @@
     },
     {
         "rev": "aab33d13110f26604fb786878856ec0b9e5fc32b",
+        "parents": ["b73791563d2f218806786090fb49ef70faa51a3a"],
         "title": "Bump version: 1.0.0b1 → 1.0.0b2",
         "body": "",
         "author": "Commitizen",
@@ -262,6 +300,7 @@
     },
     {
         "rev": "b73791563d2f218806786090fb49ef70faa51a3a",
+        "parents": ["7aa06a454fb717408b3657faa590731fb4ab3719"],
         "title": "docs(README): updated to reflect current state",
         "body": "",
         "author": "Commitizen",
@@ -269,6 +308,10 @@
     },
     {
         "rev": "7aa06a454fb717408b3657faa590731fb4ab3719",
+        "parents": [
+            "7c7e96b723c2aaa1aec3a52561f680adf0b60e97",
+            "9589a65880016996cff156b920472b9d28d771ca",
+        ],
         "title": "Merge pull request #9 from Woile/dev",
         "body": "feat: py3 only, tests and conventional commits 1.0",
         "author": "Commitizen",
@@ -276,6 +319,7 @@
     },
     {
         "rev": "7c7e96b723c2aaa1aec3a52561f680adf0b60e97",
+        "parents": ["ed830019581c83ba633bfd734720e6758eca6061"],
         "title": "Bump version: 0.9.11 → 1.0.0b1",
         "body": "",
         "author": "Commitizen",
@@ -283,6 +327,7 @@
     },
     {
         "rev": "ed830019581c83ba633bfd734720e6758eca6061",
+        "parents": ["c52eca6f74f844ab3ffbde61d98ef96071e132b7"],
         "title": "feat: py3 only, tests and conventional commits 1.0",
         "body": "more tests\npyproject instead of Pipfile\nquestionary instead of whaaaaat (promptkit 2.0.0 support)",
         "author": "Commitizen",
@@ -290,6 +335,7 @@
     },
     {
         "rev": "c52eca6f74f844ab3ffbde61d98ef96071e132b7",
+        "parents": ["0326652b2657083929507ee66d4d1a0899e861ba"],
         "title": "Bump version: 0.9.10 → 0.9.11",
         "body": "",
         "author": "Commitizen",
@@ -297,6 +343,7 @@
     },
     {
         "rev": "0326652b2657083929507ee66d4d1a0899e861ba",
+        "parents": ["b3f89892222340150e32631ae6b7aab65230036f"],
         "title": "fix(config): load config reads in order without failing if there is no commitizen section",
         "body": "Closes #8",
         "author": "Commitizen",
@@ -304,6 +351,7 @@
     },
     {
         "rev": "b3f89892222340150e32631ae6b7aab65230036f",
+        "parents": ["5e837bf8ef0735193597372cd2d85e31a8f715b9"],
         "title": "Bump version: 0.9.9 → 0.9.10",
         "body": "",
         "author": "Commitizen",
@@ -311,6 +359,7 @@
     },
     {
         "rev": "5e837bf8ef0735193597372cd2d85e31a8f715b9",
+        "parents": ["684e0259cc95c7c5e94854608cd3dcebbd53219e"],
         "title": "fix: parse scope (this is my punishment for not having tests)",
         "body": "",
         "author": "Commitizen",
@@ -318,6 +367,7 @@
     },
     {
         "rev": "684e0259cc95c7c5e94854608cd3dcebbd53219e",
+        "parents": ["ca38eac6ff09870851b5c76a6ff0a2a8e5ecda15"],
         "title": "Bump version: 0.9.8 → 0.9.9",
         "body": "",
         "author": "Commitizen",
@@ -325,6 +375,7 @@
     },
     {
         "rev": "ca38eac6ff09870851b5c76a6ff0a2a8e5ecda15",
+        "parents": ["64168f18d4628718c49689ee16430549e96c5d4b"],
         "title": "fix: parse scope empty",
         "body": "",
         "author": "Commitizen",
@@ -332,6 +383,7 @@
     },
     {
         "rev": "64168f18d4628718c49689ee16430549e96c5d4b",
+        "parents": ["9d4def716ef235a1fa5ae61614366423fbc8256f"],
         "title": "Bump version: 0.9.7 → 0.9.8",
         "body": "",
         "author": "Commitizen",
@@ -339,6 +391,7 @@
     },
     {
         "rev": "9d4def716ef235a1fa5ae61614366423fbc8256f",
+        "parents": ["33b0bf1a0a4dc60aac45ed47476d2e5473add09e"],
         "title": "fix(scope): parse correctly again",
         "body": "",
         "author": "Commitizen",
@@ -346,6 +399,7 @@
     },
     {
         "rev": "33b0bf1a0a4dc60aac45ed47476d2e5473add09e",
+        "parents": ["696885e891ec35775daeb5fec3ba2ab92c2629e1"],
         "title": "Bump version: 0.9.6 → 0.9.7",
         "body": "",
         "author": "Commitizen",
@@ -353,6 +407,7 @@
     },
     {
         "rev": "696885e891ec35775daeb5fec3ba2ab92c2629e1",
+        "parents": ["bef4a86761a3bda309c962bae5d22ce9b57119e4"],
         "title": "fix(scope): parse correctly",
         "body": "",
         "author": "Commitizen",
@@ -360,6 +415,7 @@
     },
     {
         "rev": "bef4a86761a3bda309c962bae5d22ce9b57119e4",
+        "parents": ["72472efb80f08ee3fd844660afa012c8cb256e4b"],
         "title": "Bump version: 0.9.5 → 0.9.6",
         "body": "",
         "author": "Commitizen",
@@ -367,6 +423,7 @@
     },
     {
         "rev": "72472efb80f08ee3fd844660afa012c8cb256e4b",
+        "parents": ["b5561ce0ab3b56bb87712c8f90bcf37cf2474f1b"],
         "title": "refactor(conventionalCommit): moved filters to questions instead of message",
         "body": "",
         "author": "Commitizen",
@@ -374,6 +431,7 @@
     },
     {
         "rev": "b5561ce0ab3b56bb87712c8f90bcf37cf2474f1b",
+        "parents": ["3e31714dc737029d96898f412e4ecd2be1bcd0ce"],
         "title": "fix(manifest): included missing files",
         "body": "",
         "author": "Commitizen",
@@ -381,6 +439,7 @@
     },
     {
         "rev": "3e31714dc737029d96898f412e4ecd2be1bcd0ce",
+        "parents": ["9df721e06595fdd216884c36a28770438b4f4a39"],
         "title": "Bump version: 0.9.4 → 0.9.5",
         "body": "",
         "author": "Commitizen",
@@ -388,6 +447,7 @@
     },
     {
         "rev": "9df721e06595fdd216884c36a28770438b4f4a39",
+        "parents": ["0cf6ada372470c8d09e6c9e68ebf94bbd5a1656f"],
         "title": "fix(config): home path for python versions between 3.0 and 3.5",
         "body": "",
         "author": "Commitizen",
@@ -395,6 +455,7 @@
     },
     {
         "rev": "0cf6ada372470c8d09e6c9e68ebf94bbd5a1656f",
+        "parents": ["973c6b3e100f6f69a3fe48bd8ee55c135b96c318"],
         "title": "Bump version: 0.9.3 → 0.9.4",
         "body": "",
         "author": "Commitizen",
@@ -402,6 +463,7 @@
     },
     {
         "rev": "973c6b3e100f6f69a3fe48bd8ee55c135b96c318",
+        "parents": ["dacc86159b260ee98eb5f57941c99ba731a01399"],
         "title": "feat(cli): added version",
         "body": "",
         "author": "Commitizen",
@@ -409,6 +471,7 @@
     },
     {
         "rev": "dacc86159b260ee98eb5f57941c99ba731a01399",
+        "parents": ["4368f3c3cbfd4a1ced339212230d854bc5bab496"],
         "title": "Bump version: 0.9.2 → 0.9.3",
         "body": "",
         "author": "Commitizen",
@@ -416,6 +479,7 @@
     },
     {
         "rev": "4368f3c3cbfd4a1ced339212230d854bc5bab496",
+        "parents": ["da94133288727d35dae9b91866a25045038f2d38"],
         "title": "feat(committer): conventional commit is a bit more intelligent now",
         "body": "",
         "author": "Commitizen",
@@ -423,6 +487,7 @@
     },
     {
         "rev": "da94133288727d35dae9b91866a25045038f2d38",
+        "parents": ["1541f54503d2e1cf39bd777c0ca5ab5eb78772ba"],
         "title": "docs(README): motivation",
         "body": "",
         "author": "Commitizen",
@@ -430,6 +495,7 @@
     },
     {
         "rev": "1541f54503d2e1cf39bd777c0ca5ab5eb78772ba",
+        "parents": ["ddc855a637b7879108308b8dbd85a0fd27c7e0e7"],
         "title": "Bump version: 0.9.1 → 0.9.2",
         "body": "",
         "author": "Commitizen",
@@ -437,6 +503,7 @@
     },
     {
         "rev": "ddc855a637b7879108308b8dbd85a0fd27c7e0e7",
+        "parents": ["46e9032e18a819e466618c7a014bcb0e9981af9e"],
         "title": "refactor: renamed conventional_changelog to conventional_commits, not backward compatible",
         "body": "",
         "author": "Commitizen",
@@ -444,6 +511,7 @@
     },
     {
         "rev": "46e9032e18a819e466618c7a014bcb0e9981af9e",
+        "parents": ["0fef73cd7dc77a25b82e197e7c1d3144a58c1350"],
         "title": "Bump version: 0.9.0 → 0.9.1",
         "body": "",
         "author": "Commitizen",
@@ -451,6 +519,7 @@
     },
     {
         "rev": "0fef73cd7dc77a25b82e197e7c1d3144a58c1350",
+        "parents": [],
         "title": "fix(setup.py): future is now required for every python version",
         "body": "",
         "author": "Commitizen",
@@ -489,6 +558,7 @@ def gitcommits() -> list:
             commit["body"],
             commit["author"],
             commit["author_email"],
+            commit["parents"],
         )
         for commit in COMMITS_DATA
     ]
@@ -1108,6 +1178,7 @@ def test_generate_tree_from_commits(gitcommits, tags, merge_prereleases):
                 assert change["author"] == "Commitizen"
                 assert change["author_email"] in "author@cz.dev"
                 assert "sha1" in change
+                assert "parents" in change
 
 
 def test_generate_tree_from_commits_with_no_commits(tags):

From ca410a4244bcba089ab391d3f56efc8c52d1a736 Mon Sep 17 00:00:00 2001
From: Alejandro Martinez Ruiz <alex@flawedcode.org>
Date: Fri, 21 Mar 2025 12:53:45 +0100
Subject: [PATCH 3/3] docs(customization): add "parents" to the list of fields
 in Changes

---
 docs/customization.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/docs/customization.md b/docs/customization.md
index 132f4f049..50113301d 100644
--- a/docs/customization.md
+++ b/docs/customization.md
@@ -507,12 +507,16 @@ Each `Change` has the following fields:
 | scope | `str | None` | An optional scope |
 | message | `str` | The commit message body |
 | sha1 | `str` | The commit `sha1` |
+| parents | `list[str]` | The parent commit(s) `sha1`(s) |
 | 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
 
+The `parents` field can be used to identify merge commits and generate a changelog based on those. Another use case
+is listing commits that belong to the same pull request.
+
 When using another template (either provided by a plugin or by yourself), you can also pass extra template variables
 by: