From 4df54cc664506dfa234dc61033a5dce65681a618 Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Tue, 13 Jan 2026 23:04:28 -0500 Subject: [PATCH 01/10] feat(prek): support 'prek' as an alternative to 'pre-commit' in project_info --- commitizen/project_info.py | 2 +- tests/test_project_info.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/commitizen/project_info.py b/commitizen/project_info.py index a75438800..9ca0d9e3b 100644 --- a/commitizen/project_info.py +++ b/commitizen/project_info.py @@ -6,7 +6,7 @@ def is_pre_commit_installed() -> bool: - return bool(shutil.which("pre-commit")) + return bool(shutil.which("pre-commit")) or bool(shutil.which("prek")) def get_default_version_provider() -> Literal[ diff --git a/tests/test_project_info.py b/tests/test_project_info.py index d30a743e5..9fe26d361 100644 --- a/tests/test_project_info.py +++ b/tests/test_project_info.py @@ -22,6 +22,7 @@ def _create_project_files(files: dict[str, str | None]) -> None: "which_return, expected", [ ("/usr/local/bin/pre-commit", True), + ("/usr/local/bin/prek", True), (None, False), ("", False), ], From 66f5782bcb99797df6566cd9a00ca42817f12e82 Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Tue, 13 Jan 2026 23:08:09 -0500 Subject: [PATCH 02/10] build(prek): replace 'pre-commit' with 'prek' in project configuration --- pyproject.toml | 6 +-- tests/test_bump_create_commit_message.py | 4 +- uv.lock | 69 +++++++++--------------- 3 files changed, 30 insertions(+), 49 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7262a5dd1..3c752d849 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -111,13 +111,13 @@ test = [ linters = [ "ruff>=0.11.5", - "pre-commit>=3.2.0", "mypy>=1.16.0", "types-deprecated>=1.2.9.2", "types-python-dateutil>=2.8.19.13", "types-PyYAML>=5.4.3", "types-termcolor>=0.1.1", "types-colorama>=0.4.15.20240311", + "prek>=0.2.28", ] documentation = ["mkdocs>=1.4.2", "mkdocs-material>=9.1.6"] @@ -303,8 +303,8 @@ doc.help = "Live documentation server" doc.cmd = "mkdocs serve" ci.help = "Run all tasks in CI" -ci.sequence = ["check-commit", { cmd = "pre-commit run --all-files" }, "cover"] +ci.sequence = ["check-commit", { cmd = "prek run --all-files" }, "cover"] ci.env = { SKIP = "no-commit-to-branch" } setup-pre-commit.help = "Install pre-commit hooks" -setup-pre-commit.cmd = "pre-commit install" +setup-pre-commit.cmd = "prek install" diff --git a/tests/test_bump_create_commit_message.py b/tests/test_bump_create_commit_message.py index 0477b5eeb..41f090d59 100644 --- a/tests/test_bump_create_commit_message.py +++ b/tests/test_bump_create_commit_message.py @@ -69,7 +69,7 @@ def test_bump_pre_commit_changelog(util: UtilFixture, retry): ) cmd.run("git add -A") cmd.run('git commit -m "fix: _test"') - cmd.run("pre-commit install") + cmd.run("prek install") util.run_cli(*bump_args) # Pre-commit fixed last line adding extra indent and "\" char assert Path("CHANGELOG.md").read_text() == dedent( @@ -106,7 +106,7 @@ def test_bump_pre_commit_changelog_fails_always(util: UtilFixture, retry): ) cmd.run("git add -A") cmd.run('git commit -m "feat: forbid changelogs"') - cmd.run("pre-commit install") + cmd.run("prek install") with pytest.raises(exceptions.BumpCommitFailedError): util.run_cli(*bump_args) diff --git a/uv.lock b/uv.lock index 924995d6d..ce9bdb4ed 100644 --- a/uv.lock +++ b/uv.lock @@ -65,15 +65,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, ] -[[package]] -name = "cfgv" -version = "3.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, -] - [[package]] name = "chardet" version = "5.2.0" @@ -224,7 +215,7 @@ dev = [ { name = "mkdocs-material" }, { name = "mypy" }, { name = "poethepoet" }, - { name = "pre-commit" }, + { name = "prek" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "pytest-freezer" }, @@ -248,7 +239,7 @@ documentation = [ ] linters = [ { name = "mypy" }, - { name = "pre-commit" }, + { name = "prek" }, { name = "ruff" }, { name = "types-colorama" }, { name = "types-deprecated" }, @@ -295,7 +286,7 @@ dev = [ { name = "mkdocs-material", specifier = ">=9.1.6" }, { name = "mypy", specifier = ">=1.16.0" }, { name = "poethepoet", specifier = ">=0.34.0" }, - { name = "pre-commit", specifier = ">=3.2.0" }, + { name = "prek", specifier = ">=0.2.28" }, { name = "pytest", specifier = ">=9" }, { name = "pytest-cov", specifier = ">=4" }, { name = "pytest-freezer", specifier = ">=0.4.6" }, @@ -319,7 +310,7 @@ documentation = [ ] linters = [ { name = "mypy", specifier = ">=1.16.0" }, - { name = "pre-commit", specifier = ">=3.2.0" }, + { name = "prek", specifier = ">=0.2.28" }, { name = "ruff", specifier = ">=0.11.5" }, { name = "types-colorama", specifier = ">=0.4.15.20240311" }, { name = "types-deprecated", specifier = ">=1.2.9.2" }, @@ -544,15 +535,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, ] -[[package]] -name = "identify" -version = "2.6.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, -] - [[package]] name = "idna" version = "3.11" @@ -990,15 +972,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] -[[package]] -name = "nodeenv" -version = "1.9.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, -] - [[package]] name = "packaging" version = "25.0" @@ -1089,19 +1062,27 @@ wheels = [ ] [[package]] -name = "pre-commit" -version = "4.5.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cfgv" }, - { name = "identify" }, - { name = "nodeenv" }, - { name = "pyyaml" }, - { name = "virtualenv" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232, upload-time = "2025-12-16T21:14:33.552Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437, upload-time = "2025-12-16T21:14:32.409Z" }, +name = "prek" +version = "0.2.28" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/d7/dda8a6b7819bdb9d1f54fa046911e80974d862bacba75a3539b43a9bb858/prek-0.2.28.tar.gz", hash = "sha256:ac54f58cad26e617a5c5459b705ff1cbaaa41640db03d8d35e39645aca1b82cf", size = 283945, upload-time = "2026-01-13T15:12:20.185Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/8c/2e18867e31d06dfa4974bf31c4e597dc1d2b3671b3c04d85f1f6a32ebc74/prek-0.2.28-py3-none-linux_armv6l.whl", hash = "sha256:1705c0bd035379cb5f1d03c19481821363d72d7923303fe8c84fd8cc7c6c3318", size = 4802811, upload-time = "2026-01-13T15:12:14.698Z" }, + { url = "https://files.pythonhosted.org/packages/26/fa/6c6d0b0d8b2f21301da2bb3441f22232ed5a8cba1b63eeb18244d2192a2e/prek-0.2.28-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:67677c08767c278335b31ebcbf00c1c73e14eadd99a0d8537dfb43c54482673a", size = 4904156, upload-time = "2026-01-13T15:12:21.184Z" }, + { url = "https://files.pythonhosted.org/packages/fc/5a/aa071ef1c2e6c3f58b50d9138676c96dd6de2323a44e1a3e56e18d25c382/prek-0.2.28-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ffac92215058ea6ba954a8e3f978dcd2a5e89922a318fcb7035fb9c0ab4de395", size = 4630803, upload-time = "2026-01-13T15:12:06.158Z" }, + { url = "https://files.pythonhosted.org/packages/77/dc/66498e805a0bb17820de0c3575d75b202c66045a9bfeeff9305d9bedd126/prek-0.2.28-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:413c3da1c9b252b3fd5113f4a04c2dead3c793b0ec56fc55294bb797ba7ca056", size = 4826037, upload-time = "2026-01-13T15:12:12.726Z" }, + { url = "https://files.pythonhosted.org/packages/27/ad/99cccc9283c7b34cd92356fcb301a2b1c25a8b65dc34b86c671b0f8e29d8/prek-0.2.28-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e99639bb68b70704e7b3f7f1a51cb23527c4dbd4b8a01dfccaa70f26f8f6c58b", size = 4723658, upload-time = "2026-01-13T15:12:01.538Z" }, + { url = "https://files.pythonhosted.org/packages/53/13/ce3edc2dda7b65485612e08ab038b8dd1ef7b10a94b0193f527b19a5e246/prek-0.2.28-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33c4a1b2a8a76581476ae327d6d4f1b0af6af42a90d436e21e45c72cb1081b81", size = 5044611, upload-time = "2026-01-13T15:12:26.331Z" }, + { url = "https://files.pythonhosted.org/packages/48/47/6405d7ad7959d9b57d56fec9a1b4b2e00abeb955084dd45d100fb50a8377/prek-0.2.28-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6236dda18152fc56b9f802ce2914fbb2d19f9891595d552228c7894004b3332f", size = 5511371, upload-time = "2026-01-13T15:12:24.453Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/108c227fae40268ece36b80e5649037f1a816518e9b6d585d128b263df79/prek-0.2.28-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6506709d9a52ee431d48b249b8b5fb93597a9511eb260ee85d868750425057f", size = 5099352, upload-time = "2026-01-13T15:12:18.876Z" }, + { url = "https://files.pythonhosted.org/packages/12/d6/156ad3996d3a078a1bc2c0839b8681634216a494dcb298b8751beb28b327/prek-0.2.28-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:7cc920c12613440c105a767dc19acf048e8a05342ba38b48450d673bea33bd62", size = 4834340, upload-time = "2026-01-13T15:11:59.811Z" }, + { url = "https://files.pythonhosted.org/packages/f4/06/c632d4c4bb9c63d25bcc26149f99c715206a40e414fb6b80e7f800ae2e2d/prek-0.2.28-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:322a1922e6d2fcb2a4c487e01b2613856dc3206269bdc317ad28770704159e63", size = 4844870, upload-time = "2026-01-13T15:12:03.243Z" }, + { url = "https://files.pythonhosted.org/packages/ba/03/763f62d292399ee962e2583e7bc3fd2f8ee2609813c89cc10ec89a39204c/prek-0.2.28-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:a07baefe3562371368135eac3c8b9cdb831bac17b83cb1b6a8f5688050918e6c", size = 4709011, upload-time = "2026-01-13T15:12:04.701Z" }, + { url = "https://files.pythonhosted.org/packages/e1/62/49397d1a5c2aaf5e7a8c0644be901ee97934a8a2cac0052652d01b7c6585/prek-0.2.28-py3-none-musllinux_1_1_i686.whl", hash = "sha256:17e95cab33067365028ffc1d4ab6c80c6c150f88e352d7c64bdc15e0570778f6", size = 4928435, upload-time = "2026-01-13T15:11:58.147Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e8/8ec73b5bb3fb9d5daf77f181cc46c541bd476075c7613f9b4c9c953925cc/prek-0.2.28-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:bc5272e2e8d81438a3cd2785c3b14b6e73dcb8e61b8a2b7ce6e693d57f7181ac", size = 5209880, upload-time = "2026-01-13T15:12:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/f3/52/a784a52bf72619bdfaafdbb6c964bda404b377213e7dc786f9ad6024501c/prek-0.2.28-py3-none-win32.whl", hash = "sha256:74657a1663191fb5f09f15873704c2d2640095ce56277d36860bbd08ba7eea94", size = 4622786, upload-time = "2026-01-13T15:12:22.967Z" }, + { url = "https://files.pythonhosted.org/packages/d0/b8/ec6aafefeb05ef3a0bfcc044d036890f2b732b90ed1426acbf1e33289a44/prek-0.2.28-py3-none-win_amd64.whl", hash = "sha256:c350046d623362db65e2be1455ef1c5a96ea476e235445752fa946a705f1c1c9", size = 5316389, upload-time = "2026-01-13T15:12:17.501Z" }, + { url = "https://files.pythonhosted.org/packages/df/3f/9d4aba92cb9199cad0b056de8292a78dcca1dc1f6a6a34550799f19bde3d/prek-0.2.28-py3-none-win_arm64.whl", hash = "sha256:81db6ba7e5cf1d5ceec7d3b04e01aded32b8db8f1238ad812ac6ebc0bd35f141", size = 4974627, upload-time = "2026-01-13T15:11:56.333Z" }, ] [[package]] From 8e4c6cb8d3dde808338df3a2e477bf2f97c0011a Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 00:32:01 -0500 Subject: [PATCH 03/10] docs(auto_check): update installation instructions to include 'prek' as an alternative to 'pre-commit' --- docs/tutorials/auto_check.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docs/tutorials/auto_check.md b/docs/tutorials/auto_check.md index d877d5009..d91f6e8dc 100644 --- a/docs/tutorials/auto_check.md +++ b/docs/tutorials/auto_check.md @@ -10,9 +10,9 @@ When a commit message fails validation, Git will reject the commit and display a There are two common methods for installing the hooks: -### Method 1: Using [pre-commit](https://pre-commit.com/) (Recommended) +### Method 1: Using [pre-commit](https://pre-commit.com/) or [prek](https://prek.j178.dev) (Recommended) -[pre-commit](https://pre-commit.com/) is a framework for managing and maintaining multi-language pre-commit hooks. It's the recommended approach as it handles hook installation, updates, and execution automatically. +[pre-commit](https://pre-commit.com/) and [prek](https://prek.j178.dev) are frameworks for managing and maintaining multi-language pre-commit hooks. It's the recommended approach as it handles hook installation, updates, and execution automatically. #### Step 1: Install pre-commit @@ -20,6 +20,12 @@ There are two common methods for installing the hooks: python -m pip install pre-commit ``` +or + +```sh +python -m pip install prek +``` + #### Step 2: Create `.pre-commit-config.yaml` Create a `.pre-commit-config.yaml` file in your project root directory with the following content: @@ -45,6 +51,12 @@ Install the configuration into Git's hook system: pre-commit install --hook-type commit-msg ``` +or + +```bash +prek install --hook-type commit-msg +``` + The hook is now active! Every time you create a commit, commitizen will automatically validate your commit message. ### Method 2: Manual Git hook installation From 75295e597b794edbab1c9c791a719e79cdac53a1 Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 00:46:46 -0500 Subject: [PATCH 04/10] test: brought back the `pre-commit` tests along with `prek` --- pyproject.toml | 1 + tests/test_bump_create_commit_message.py | 10 +++-- uv.lock | 47 ++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3c752d849..7545d0efb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -107,6 +107,7 @@ test = [ "pytest-freezer>=0.4.6", "pytest-xdist>=3.1.0", "pytest-gitconfig>=0.9.0", + "pre-commit>=4.5.1", ] linters = [ diff --git a/tests/test_bump_create_commit_message.py b/tests/test_bump_create_commit_message.py index 41f090d59..bdafd2364 100644 --- a/tests/test_bump_create_commit_message.py +++ b/tests/test_bump_create_commit_message.py @@ -24,6 +24,7 @@ def test_create_tag(test_input, expected): assert new_tag == expected +@pytest.mark.parametrize("hook_runner", ("pre-commit", "prek")) @pytest.mark.parametrize( "retry", ( @@ -38,7 +39,7 @@ def test_create_tag(test_input, expected): ), ) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_pre_commit_changelog(util: UtilFixture, retry): +def test_bump_pre_commit_changelog(util: UtilFixture, retry, hook_runner): util.freezer.move_to("2022-04-01") bump_args = ["bump", "--changelog", "--yes"] if retry: @@ -69,7 +70,7 @@ def test_bump_pre_commit_changelog(util: UtilFixture, retry): ) cmd.run("git add -A") cmd.run('git commit -m "fix: _test"') - cmd.run("prek install") + cmd.run(f"{hook_runner} install") util.run_cli(*bump_args) # Pre-commit fixed last line adding extra indent and "\" char assert Path("CHANGELOG.md").read_text() == dedent( @@ -83,9 +84,10 @@ def test_bump_pre_commit_changelog(util: UtilFixture, retry): ) +@pytest.mark.parametrize("hook_runner", ("pre-commit", "prek")) @pytest.mark.parametrize("retry", (True, False)) @pytest.mark.usefixtures("tmp_commitizen_project") -def test_bump_pre_commit_changelog_fails_always(util: UtilFixture, retry): +def test_bump_pre_commit_changelog_fails_always(util: UtilFixture, retry, hook_runner): util.freezer.move_to("2022-04-01") bump_args = ["bump", "--changelog", "--yes"] if retry: @@ -106,7 +108,7 @@ def test_bump_pre_commit_changelog_fails_always(util: UtilFixture, retry): ) cmd.run("git add -A") cmd.run('git commit -m "feat: forbid changelogs"') - cmd.run("prek install") + cmd.run(f"{hook_runner} install") with pytest.raises(exceptions.BumpCommitFailedError): util.run_cli(*bump_args) diff --git a/uv.lock b/uv.lock index ce9bdb4ed..c482e9a43 100644 --- a/uv.lock +++ b/uv.lock @@ -65,6 +65,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, ] +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + [[package]] name = "chardet" version = "5.2.0" @@ -215,6 +224,7 @@ dev = [ { name = "mkdocs-material" }, { name = "mypy" }, { name = "poethepoet" }, + { name = "pre-commit" }, { name = "prek" }, { name = "pytest" }, { name = "pytest-cov" }, @@ -251,6 +261,7 @@ script = [ { name = "rich" }, ] test = [ + { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-cov" }, { name = "pytest-freezer" }, @@ -286,6 +297,7 @@ dev = [ { name = "mkdocs-material", specifier = ">=9.1.6" }, { name = "mypy", specifier = ">=1.16.0" }, { name = "poethepoet", specifier = ">=0.34.0" }, + { name = "pre-commit", specifier = ">=4.5.1" }, { name = "prek", specifier = ">=0.2.28" }, { name = "pytest", specifier = ">=9" }, { name = "pytest-cov", specifier = ">=4" }, @@ -320,6 +332,7 @@ linters = [ ] script = [{ name = "rich", specifier = ">=13.7.1" }] test = [ + { name = "pre-commit", specifier = ">=4.5.1" }, { name = "pytest", specifier = ">=9" }, { name = "pytest-cov", specifier = ">=4" }, { name = "pytest-freezer", specifier = ">=0.4.6" }, @@ -535,6 +548,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, ] +[[package]] +name = "identify" +version = "2.6.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5b/8d/e8b97e6bd3fb6fb271346f7981362f1e04d6a7463abd0de79e1fda17c067/identify-2.6.16.tar.gz", hash = "sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980", size = 99360, upload-time = "2026-01-12T18:58:58.201Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/58/40fbbcefeda82364720eba5cf2270f98496bdfa19ea75b4cccae79c698e6/identify-2.6.16-py2.py3-none-any.whl", hash = "sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0", size = 99202, upload-time = "2026-01-12T18:58:56.627Z" }, +] + [[package]] name = "idna" version = "3.11" @@ -972,6 +994,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + [[package]] name = "packaging" version = "25.0" @@ -1061,6 +1092,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/38/89/2bf7d43ef4b0d60f446933ae9d3649f95c2c45c47b6736d121b602c28361/poethepoet-0.38.0-py3-none-any.whl", hash = "sha256:214bd9fcb348ff3dfd1466579d67e0c02242451a7044aced1a79641adef9cad0", size = 101938, upload-time = "2025-11-23T13:51:26.518Z" }, ] +[[package]] +name = "pre-commit" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232, upload-time = "2025-12-16T21:14:33.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437, upload-time = "2025-12-16T21:14:32.409Z" }, +] + [[package]] name = "prek" version = "0.2.28" From d17220931899a08a86cbc37c1f0b10f452995315 Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 00:56:16 -0500 Subject: [PATCH 05/10] docs(README): update badge to reflect support for 'prek' instead of 'pre-commit' --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index ad0911e3a..bf62a391c 100644 --- a/docs/README.md +++ b/docs/README.md @@ -7,7 +7,7 @@ [![Conda Version](https://img.shields.io/conda/vn/conda-forge/commitizen?style=flat-square)](https://anaconda.org/conda-forge/commitizen) [![homebrew](https://img.shields.io/homebrew/v/commitizen?color=teal&style=flat-square)](https://formulae.brew.sh/formula/commitizen) [![Codecov](https://img.shields.io/codecov/c/github/commitizen-tools/commitizen.svg?style=flat-square)](https://codecov.io/gh/commitizen-tools/commitizen) -[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?style=flat-square&logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit) +[![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json&style=flat-square&color=brightgreen)](https://github.com/j178/prek) ![Using Commitizen cli](images/demo.gif) From 85ad7c0da63f0220abda04a237d18749695c0a53 Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 00:59:06 -0500 Subject: [PATCH 06/10] refactor(project_info): enhance pre-commit check to support multiple tools --- commitizen/project_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commitizen/project_info.py b/commitizen/project_info.py index 9ca0d9e3b..381629304 100644 --- a/commitizen/project_info.py +++ b/commitizen/project_info.py @@ -6,7 +6,7 @@ def is_pre_commit_installed() -> bool: - return bool(shutil.which("pre-commit")) or bool(shutil.which("prek")) + return any(shutil.which(tool) for tool in ("pre-commit", "prek")) def get_default_version_provider() -> Literal[ From f0040435475e4c6b15f10693921590183db37011 Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 01:00:36 -0500 Subject: [PATCH 07/10] docs(auto_check): update auto check installation by only keeping one example --- docs/tutorials/auto_check.md | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/docs/tutorials/auto_check.md b/docs/tutorials/auto_check.md index d91f6e8dc..86a9b9e5e 100644 --- a/docs/tutorials/auto_check.md +++ b/docs/tutorials/auto_check.md @@ -10,22 +10,20 @@ When a commit message fails validation, Git will reject the commit and display a There are two common methods for installing the hooks: -### Method 1: Using [pre-commit](https://pre-commit.com/) or [prek](https://prek.j178.dev) (Recommended) +### Method 1: Using pre-commit hook frameworks (Recommended) -[pre-commit](https://pre-commit.com/) and [prek](https://prek.j178.dev) are frameworks for managing and maintaining multi-language pre-commit hooks. It's the recommended approach as it handles hook installation, updates, and execution automatically. +Using pre-commit frameworks is the recommended approach as hook installation, updates, and execution are handled automatically. +These are two common pre-commit hooks: +- [prek](https://prek.j178.dev) (faster) +- [pre-commit](https://pre-commit.com/) -#### Step 1: Install pre-commit - -```sh -python -m pip install pre-commit -``` - -or +#### Step 1: Install prek ```sh python -m pip install prek ``` + #### Step 2: Create `.pre-commit-config.yaml` Create a `.pre-commit-config.yaml` file in your project root directory with the following content: @@ -47,16 +45,11 @@ repos: Install the configuration into Git's hook system: -```bash -pre-commit install --hook-type commit-msg -``` - -or - ```bash prek install --hook-type commit-msg ``` + The hook is now active! Every time you create a commit, commitizen will automatically validate your commit message. ### Method 2: Manual Git hook installation From 594b0ecbb1f4201263e6718ab4aeb59fa94bb94c Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 01:23:32 -0500 Subject: [PATCH 08/10] docs: update documentation to reflect 'prek' integration and improve clarity --- docs/README.md | 9 +++++---- docs/tutorials/auto_check.md | 25 +++++++++++++------------ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/docs/README.md b/docs/README.md index bf62a391c..da49c3166 100644 --- a/docs/README.md +++ b/docs/README.md @@ -182,7 +182,7 @@ This command is particularly useful for automation scripts and CI/CD pipelines. For example, you can use the output of the command `cz changelog --dry-run "$(cz version -p)"` to notify your team about a new release in Slack. -#### Pre-commit Integration +#### Prek and Pre-commit Integration Commitizen can automatically validate your commit messages using pre-commit hooks. @@ -200,7 +200,7 @@ repos: 2. Install the hooks: ```sh -pre-commit install --hook-type commit-msg --hook-type pre-push +prek install --hook-type commit-msg --hook-type pre-push ``` | Hook | Recommended Stage | @@ -208,9 +208,10 @@ pre-commit install --hook-type commit-msg --hook-type pre-push | commitizen | commit-msg | | commitizen-branch | pre-push | -> **Note**: Replace `master` with the [latest tag](https://github.com/commitizen-tools/commitizen/tags) to avoid warnings. You can automatically update this with: +> [!Note] +> Replace `master` with the [latest tag](https://github.com/commitizen-tools/commitizen/tags) to avoid warnings. You can automatically update this with: > ```sh -> pre-commit autoupdate +> prek autoupdate > ``` For more details about commit validation, see the [check command documentation](https://commitizen-tools.github.io/commitizen/commands/check/). diff --git a/docs/tutorials/auto_check.md b/docs/tutorials/auto_check.md index 86a9b9e5e..692abc591 100644 --- a/docs/tutorials/auto_check.md +++ b/docs/tutorials/auto_check.md @@ -2,9 +2,9 @@ ## About -To automatically check a commit message prior to committing, you can use a [Git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks). This ensures that all commit messages follow your project's commitizen format before they are accepted into the repository. +To automatically check a commit message before committing, use a [Git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks). This ensures all commit messages match your project's commitizen format before they are accepted into the repository. -When a commit message fails validation, Git will reject the commit and display an error message explaining what went wrong. You'll need to amend your commit message to follow the required format before the commit can proceed. +When a commit message fails validation, Git rejects the commit and displays an error explaining what went wrong. Update the message to the required format before trying again. ## How to @@ -12,18 +12,19 @@ There are two common methods for installing the hooks: ### Method 1: Using pre-commit hook frameworks (Recommended) -Using pre-commit frameworks is the recommended approach as hook installation, updates, and execution are handled automatically. -These are two common pre-commit hooks: +Using pre-commit hook frameworks is the recommended approach because hook installation, updates, and execution are handled automatically. +Two common frameworks are: - [prek](https://prek.j178.dev) (faster) - [pre-commit](https://pre-commit.com/) +In the steps below, we'll use `prek`. + #### Step 1: Install prek ```sh python -m pip install prek ``` - #### Step 2: Create `.pre-commit-config.yaml` Create a `.pre-commit-config.yaml` file in your project root directory with the following content: @@ -49,12 +50,11 @@ Install the configuration into Git's hook system: prek install --hook-type commit-msg ``` - The hook is now active! Every time you create a commit, commitizen will automatically validate your commit message. ### Method 2: Manual Git hook installation -If you prefer not to use pre-commit, you can manually create a Git hook. This gives you full control over the hook script but requires manual maintenance. +If you prefer not to use a pre-commit framework, you can manually create a Git hook. This gives you full control over the hook script but requires manual maintenance. #### Step 1: Create the commit-msg hook @@ -95,7 +95,7 @@ git commit -m "invalid commit message" git commit -m "feat: add new feature" ``` -If the hook is working correctly, invalid commit messages will be rejected with an error message explaining what's wrong. +If the hook is working correctly, invalid commit messages are rejected with an error explaining what's wrong. ## What happens when validation fails? @@ -128,12 +128,12 @@ pattern: ^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\)) - **Verify commitizen is installed**: Run `cz --version` to confirm commitizen is available in your PATH - **Check Git version**: Ensure you're using a recent version of Git that supports hooks -### Pre-commit hook not working +### Prek hook not working -- **Verify installation**: Run `pre-commit --version` to confirm pre-commit is installed -- **Reinstall the hook**: Try running `pre-commit install --hook-type commit-msg` again +- **Verify installation**: Run `prek --version` to confirm pre-commit is installed +- **Reinstall the hook**: Try running `prek install --hook-type commit-msg` again - **Check configuration**: Verify your `.pre-commit-config.yaml` file is valid YAML and in the project root -- **Update hooks**: Run `pre-commit autoupdate` to update to the latest versions +- **Update hooks**: Run `prek autoupdate` to update to the latest versions ### Bypassing the hook (when needed) @@ -150,4 +150,5 @@ git commit --no-verify -m "your message" - Learn more about [Git hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) - See the [check command documentation](../commands/check.md) for more validation options +- Check out [prek documentation](https://prek.j178.dev/) for advanced hook management - Check out [pre-commit documentation](https://pre-commit.com/) for advanced hook management From cdca0fcfa579674bd694b50b294ca6fef88e7439 Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 01:27:46 -0500 Subject: [PATCH 09/10] docs(auto_check): add tip for using pre-commit framework alongside prek --- docs/tutorials/auto_check.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/tutorials/auto_check.md b/docs/tutorials/auto_check.md index 692abc591..52d370210 100644 --- a/docs/tutorials/auto_check.md +++ b/docs/tutorials/auto_check.md @@ -19,6 +19,10 @@ Two common frameworks are: In the steps below, we'll use `prek`. +!!! tip "Using pre-commit framework" + Replace `prek` with `pre-commit` in the steps below if you prefer that tool. The configuration format is similar. + + #### Step 1: Install prek ```sh From 9ad3b9d12332c8699dbd1705585333f8707d271f Mon Sep 17 00:00:00 2001 From: Yazdan Ranjbar Date: Wed, 14 Jan 2026 01:33:22 -0500 Subject: [PATCH 10/10] docs: improve formatting and clarity for rendering --- docs/README.md | 3 +-- docs/tutorials/auto_check.md | 8 ++++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/README.md b/docs/README.md index da49c3166..97cd2880d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -208,8 +208,7 @@ prek install --hook-type commit-msg --hook-type pre-push | commitizen | commit-msg | | commitizen-branch | pre-push | -> [!Note] -> Replace `master` with the [latest tag](https://github.com/commitizen-tools/commitizen/tags) to avoid warnings. You can automatically update this with: +> **Note**: Replace `master` with the [latest tag](https://github.com/commitizen-tools/commitizen/tags) to avoid warnings. You can automatically update this with: > ```sh > prek autoupdate > ``` diff --git a/docs/tutorials/auto_check.md b/docs/tutorials/auto_check.md index 52d370210..be0203239 100644 --- a/docs/tutorials/auto_check.md +++ b/docs/tutorials/auto_check.md @@ -14,15 +14,19 @@ There are two common methods for installing the hooks: Using pre-commit hook frameworks is the recommended approach because hook installation, updates, and execution are handled automatically. Two common frameworks are: -- [prek](https://prek.j178.dev) (faster) -- [pre-commit](https://pre-commit.com/) + +1. [prek](https://prek.j178.dev) (faster) +2. [pre-commit](https://pre-commit.com/) + In the steps below, we'll use `prek`. + !!! tip "Using pre-commit framework" Replace `prek` with `pre-commit` in the steps below if you prefer that tool. The configuration format is similar. + #### Step 1: Install prek ```sh