René's URL Explorer Experiment


Title: fix(cz_customize): derive bump_map_major_version_zero from custom bump_map by bearomorphism · Pull Request #1977 · commitizen-tools/commitizen · GitHub

Open Graph Title: fix(cz_customize): derive bump_map_major_version_zero from custom bump_map by bearomorphism · Pull Request #1977 · commitizen-tools/commitizen

X Title: fix(cz_customize): derive bump_map_major_version_zero from custom bump_map by bearomorphism · Pull Request #1977 · commitizen-tools/commitizen

Description: Description Closes #1728. Why When cz_customize is active and the user sets major_version_zero = true, commitizen's bump command selects self.cz.bump_map_major_version_zero instead of self.cz.bump_map to determine the version increment (see commitizen/commands/bump.py:150-154). CustomizeCommitsCz inherits bump_map_major_version_zero as a class attribute pointing at defaults.BUMP_MAP_MAJOR_VERSION_ZERO (line 30 of commitizen/cz/customize/customize.py). The __init__ attribute-copy loop (lines 40-50) only overwrites it if the user explicitly sets bump_map_major_version_zero in their [tool.commitizen.customize] section. The result is that a user who carefully crafts a bump_map — mapping feat and docs to PATCH instead of the conventional MINOR — finds that their mapping is completely ignored whenever major_version_zero = true is set. The bump falls through to defaults.BUMP_MAP_MAJOR_VERSION_ZERO, which maps feat to MINOR. The user's custom rule produces a MINOR increment when they expected PATCH, with no warning and no indication that a fallback was used. The reporter @JeannotJeannot confirmed this on commitizen 4.10.1 (Windows); a triage comment on the #1964 audit reproduced it against master (v4.15.1). The correct fix is for CustomizeCommitsCz.__init__ to derive bump_map_major_version_zero from the user's own bump_map whenever the former is absent: copy every pattern from bump_map and demote any MAJOR rule to MINOR (since the semantic purpose of major_version_zero is to prevent 1.0.0 from being crossed). Users who want a completely different mapping for the 0.x series can still set bump_map_major_version_zero explicitly; that value takes unconditional precedence. What changed File Change commitizen/cz/customize/customize.py Add _derive_major_version_zero() module-level helper; extend CustomizeCommitsCz.__init__ to call it when bump_map is set in customize settings but bump_map_major_version_zero is not tests/test_cz_customize.py Three new tests: derivation from bump_map (regression for #1728), explicit user value wins, and neither-set fallback to class default How it works MAJOR → MINOR demotion is the right semantic. The entire point of major_version_zero is that a project still in 0.x treats breaking changes as MINOR rather than MAJOR (to avoid leaving 0.x prematurely). Keeping a user's MAJOR rule as-is in the derived map would defeat that intent, so every MAJOR entry is demoted to MINOR while all MINOR and PATCH entries pass through unchanged. OrderedDict is used deliberately. commitizen/bump.py:find_increment (line 43) iterates the bump map in insertion order to find the first matching pattern. A plain dict would be fine on Python 3.7+ (insertion-ordered), but the rest of the codebase types bump_map_major_version_zero as OrderedDict[str, str] (see commitizen/defaults.py:137 and commitizen/defaults.py:17). Using OrderedDict in the derived value keeps the type consistent and preserves the user's pattern-priority order exactly. Strict trigger: both conditions must hold. The derivation only fires when self.custom_settings.get("bump_map") is truthy AND self.custom_settings.get("bump_map_major_version_zero") is falsy. This is a backwards-compatible opt-in: existing configs that already set both keys see no change; configs that set neither key continue to inherit defaults.BUMP_MAP_MAJOR_VERSION_ZERO unchanged. self.bump_map is read after the attribute-copy loop. Because the loop at lines 40-50 runs first, self.bump_map already holds the user's custom map (not the class-level default) by the time the derivation check runs. The derived bump_map_major_version_zero is therefore always consistent with whatever bump_map the bump command will actually use. Backward compatibility Configs that set both bump_map and bump_map_major_version_zero explicitly are unaffected — the not self.custom_settings.get("bump_map_major_version_zero") guard short-circuits derivation. Configs that set neither key continue to use defaults.BUMP_MAP_MAJOR_VERSION_ZERO as the class attribute — the derivation branch is never entered. All 68 existing cz_customize tests (as of master v4.15.1) continue to pass. No CLI flags, config keys, or public APIs are added or removed. Checklist I have read the contributing guidelines Was generative AI tooling used to co-author this PR? Yes (please specify the tool below) Generated-by: Claude following the guidelines Code Changes Add test cases to all the changes you introduce Run uv run poe all locally to ensure this change passes linter check and tests Manually test the changes (see "Steps to Test" below) Update the documentation for the changes Expected Behavior Scenario Outcome cz_customize with custom bump_map = {feat = "PATCH"} and major_version_zero = true, no explicit bump_map_major_version_zero cz bump --dry-run reports increment detected: PATCH — user's map is honoured Same config but with bump_map_major_version_zero explicitly set Explicit value wins unchanged — derivation does not run cz_customize with no bump_map and no bump_map_major_version_zero Falls back to defaults.BUMP_MAP_MAJOR_VERSION_ZERO — identical to current behaviour cz_customize with bump_map containing a MAJOR entry and major_version_zero = true Derived map demotes MAJOR to MINOR; no version crossing from 0.x to 1.0.0 Steps to Test This Pull Request git fetch fork fix/1728-customize-bump-map-major-zero git checkout fork/fix/1728-customize-bump-map-major-zero # 1. Targeted regression tests. uv run pytest tests/test_cz_customize.py::test_bump_map_major_version_zero_is_derived_from_bump_map \ tests/test_cz_customize.py::test_bump_map_major_version_zero_explicit_user_value_wins \ tests/test_cz_customize.py::test_bump_map_major_version_zero_falls_back_to_defaults_without_bump_map \ -v # 2. Reproduce-the-bug-then-verify-the-fix sequence (exact reproducer from #1728). mkdir cz1728 && cd cz1728 git init -b main git config user.name test && git config user.email test@example.com cat > pyproject.toml << 'EOF' [tool.commitizen] name = "cz_customize" version = "0.1.0" major_version_zero = true [tool.commitizen.customize] bump_pattern = "^(feat|fix|docs)" bump_map = {feat = "PATCH", docs = "PATCH"} EOF git add pyproject.toml && git commit -m "feat: initial setup" # Before fix: reports "increment detected: MINOR" (defaults map used). # After fix: reports "increment detected: PATCH" (user's map honoured). cz bump --dry-run --yes # Verify explicit override still wins (both maps set): sed -i 's/bump_map = .*/bump_map = {feat = "PATCH"}\nbump_map_major_version_zero = {feat = "MAJOR"}/' pyproject.toml cz bump --dry-run --yes # expect MAJOR (explicit value, not derived) Additional Context This fix was identified during the issue audit in #1964. The root cause — the gap between bump_map and bump_map_major_version_zero in cz_customize — was acknowledged in the triage comment on #1728. The workaround documented there (set both keys explicitly) remains valid for users on older releases; this PR makes the no-explicit-bump_map_major_version_zero path do the obvious thing automatically.

Open Graph Description: Description Closes #1728. Why When cz_customize is active and the user sets major_version_zero = true, commitizen's bump command selects self.cz.bump_map_major_version_zero instead of self.cz.b...

X Description: Description Closes #1728. Why When cz_customize is active and the user sets major_version_zero = true, commitizen&#39;s bump command selects self.cz.bump_map_major_version_zero instead of self....

Opengraph URL: https://github.com/commitizen-tools/commitizen/pull/1977

X: @github

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:414a23d4-38d4-1b7d-94db-7f6ae99db715
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-idD410:3885D3:9FD068:E90657:6A4E1D4A
html-safe-noncef243b48705e0621d9190fd00148dcb205ac8318ff6f9e86583ed5785602987ce
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJENDEwOjM4ODVEMzo5RkQwNjg6RTkwNjU3OjZBNEUxRDRBIiwidmlzaXRvcl9pZCI6Ijg5NjQyOTUzOTM2ODU2NzUzMzgiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ==
visitor-hmac5d0f89a29c1ad953f0e5070a1730cc1728736d5f2bddb929b7f508f62dc51145
hovercard-subject-tagpull_request:3654754860
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/commitizen-tools/commitizen/pull/1977/files
twitter:imagehttps://avatars.githubusercontent.com/u/26526132?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/u/26526132?s=400&v=4
og:image:altDescription Closes #1728. Why When cz_customize is active and the user sets major_version_zero = true, commitizen's bump command selects self.cz.bump_map_major_version_zero instead of self.cz.b...
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
None030096ee0db095447bfe77409d33bfac127ca7128299c58deef27c52eaa1b1f0
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/commitizen-tools/commitizen git https://github.com/commitizen-tools/commitizen.git
octolytics-dimension-user_id62252524
octolytics-dimension-user_logincommitizen-tools
octolytics-dimension-repository_id106127589
octolytics-dimension-repository_nwocommitizen-tools/commitizen
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id106127589
octolytics-dimension-repository_network_root_nwocommitizen-tools/commitizen
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release5fe497b4815fcce3df76c0e246faa739a82c3124
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/commitizen-tools/commitizen/pull/1977/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fcommitizen-tools%2Fcommitizen%2Fpull%2F1977%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fcommitizen-tools%2Fcommitizen%2Fpull%2F1977%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=commitizen-tools%2Fcommitizen
Reloadhttps://github.com/commitizen-tools/commitizen/pull/1977/files
Reloadhttps://github.com/commitizen-tools/commitizen/pull/1977/files
Reloadhttps://github.com/commitizen-tools/commitizen/pull/1977/files
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1977/files
commitizen-tools https://github.com/commitizen-tools
commitizenhttps://github.com/commitizen-tools/commitizen
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1977/files
Notifications https://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen
Fork 344 https://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen
Star 3.5k https://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen
Code https://github.com/commitizen-tools/commitizen
Issues 116 https://github.com/commitizen-tools/commitizen/issues
Pull requests 45 https://github.com/commitizen-tools/commitizen/pulls
Discussions https://github.com/commitizen-tools/commitizen/discussions
Actions https://github.com/commitizen-tools/commitizen/actions
Projects https://github.com/commitizen-tools/commitizen/projects
Security and quality 0 https://github.com/commitizen-tools/commitizen/security
Insights https://github.com/commitizen-tools/commitizen/pulse
Code https://github.com/commitizen-tools/commitizen
Issues https://github.com/commitizen-tools/commitizen/issues
Pull requests https://github.com/commitizen-tools/commitizen/pulls
Discussions https://github.com/commitizen-tools/commitizen/discussions
Actions https://github.com/commitizen-tools/commitizen/actions
Projects https://github.com/commitizen-tools/commitizen/projects
Security and quality https://github.com/commitizen-tools/commitizen/security
Insights https://github.com/commitizen-tools/commitizen/pulse
Sign up for GitHub https://github.com/signup?return_to=%2Fcommitizen-tools%2Fcommitizen%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2Fcommitizen-tools%2Fcommitizen%2Fissues%2Fnew%2Fchoose
bearomorphismhttps://github.com/bearomorphism
commitizen-tools:masterhttps://github.com/commitizen-tools/commitizen/tree/master
bearomorphism:fix/1728-customize-bump-map-derivehttps://github.com/bearomorphism/commitizen/tree/fix/1728-customize-bump-map-derive
Conversation 2 https://github.com/commitizen-tools/commitizen/pull/1977
Commits 1 https://github.com/commitizen-tools/commitizen/pull/1977/commits
Checks 20 https://github.com/commitizen-tools/commitizen/pull/1977/checks
Files changed 2 https://github.com/commitizen-tools/commitizen/pull/1977/files
fix(cz_customize): derive bump_map_major_version_zero from custom bump_map https://github.com/commitizen-tools/commitizen/pull/1977/files#top
Show all changes 1 commit https://github.com/commitizen-tools/commitizen/pull/1977/files
ef4650f fix(cz_customize): derive bump_map_major_version_zero from bump_map bearomorphism May 9, 2026 https://github.com/commitizen-tools/commitizen/pull/1977/commits/ef4650fc15402c8867f6a3eee71b567ce8aa3ca9
Clear filters https://github.com/commitizen-tools/commitizen/pull/1977/files
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1977/files
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1977/files
customize.py https://github.com/commitizen-tools/commitizen/pull/1977/files#diff-9902f7d08f081f8ccb8e4acb71ad8e74dfb11df78618580dc8323c3386517aa4
test_cz_customize.py https://github.com/commitizen-tools/commitizen/pull/1977/files#diff-f5ec5ad6526890a0807a07554a2e54509c6e151065e880125006cb4518281732
commitizen/cz/customize/customize.pyhttps://github.com/commitizen-tools/commitizen/pull/1977/files#diff-9902f7d08f081f8ccb8e4acb71ad8e74dfb11df78618580dc8323c3386517aa4
View file https://github.com/bearomorphism/commitizen/blob/ef4650fc15402c8867f6a3eee71b567ce8aa3ca9/commitizen/cz/customize/customize.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/commitizen-tools/commitizen/pull/1977/{{ revealButtonHref }}
https://github.com/commitizen-tools/commitizen/pull/1977/files#diff-9902f7d08f081f8ccb8e4acb71ad8e74dfb11df78618580dc8323c3386517aa4
https://github.com/commitizen-tools/commitizen/pull/1977/files#diff-9902f7d08f081f8ccb8e4acb71ad8e74dfb11df78618580dc8323c3386517aa4
https://github.com/commitizen-tools/commitizen/pull/1977/files#diff-9902f7d08f081f8ccb8e4acb71ad8e74dfb11df78618580dc8323c3386517aa4
tests/test_cz_customize.pyhttps://github.com/commitizen-tools/commitizen/pull/1977/files#diff-f5ec5ad6526890a0807a07554a2e54509c6e151065e880125006cb4518281732
View file https://github.com/bearomorphism/commitizen/blob/ef4650fc15402c8867f6a3eee71b567ce8aa3ca9/tests/test_cz_customize.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/commitizen-tools/commitizen/pull/1977/{{ revealButtonHref }}
https://github.com/commitizen-tools/commitizen/pull/1977/files#diff-f5ec5ad6526890a0807a07554a2e54509c6e151065e880125006cb4518281732
https://github.com/commitizen-tools/commitizen/pull/1977/files#diff-f5ec5ad6526890a0807a07554a2e54509c6e151065e880125006cb4518281732
Please reload this pagehttps://github.com/commitizen-tools/commitizen/pull/1977/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.