Skip to content

commitizen-branch fails with exit code: 23 and message fatal: ..: '..' is outside repository #1923

Description

@thaDude

Description

I cannot get the commitizen-branch hook to work, please see a self-contained demo in the reproduction steps below.

Steps to reproduce

I used uv to bootstrap the project

uv init commitizen-hook-test
cd commitizen-hook-test
uv add pre-commit --dev
uv add commitizen --dev
source .venv/bin/activate
# files below originally generated with cz init
cat << 'EOF' > .pre-commit-config.yaml
repos:
- hooks:
  - id: commitizen
  - id: commitizen-branch
    stages:
    - pre-push
  repo: https://github.com/commitizen-tools/commitizen
  rev: v4.13.9
EOF
cat << 'EOF' > .cz.toml
[tool.commitizen]
name = "cz_conventional_commits"
tag_format = "$version"
version_scheme = "semver2"
version_provider = "scm"
major_version_zero = true
EOF
pre-commit install --hook-type commit-msg --hook-type pre-push
git add *
git commit -am'feat: just a confirming commit'
pre-commit run --hook-stage pre-push

Clean-up

deactivate
cd ..
rm -rf commitizen-hook-test

Current behavior

The pre-push command results in:

commitizen check branch..................................................Failed
- hook id: commitizen-branch
- exit code: 23

fatal: ..: '..' is outside repository at '/Users/<redacted>/commitizen-hook-test'

Desired behavior

I would like the hook to pass.

Screenshots

No response

Environment

Commitizen Version: 4.13.9
Python Version: 3.12.3 (main, Dec 31 2024, 17:41:17) [Clang 15.0.0 (clang-1500.3.9.4)]
Operating System: Darwin

Activity

  1. natelandau commented on May 8, 2026

    @natelandau

    I ran in to the same problem, I think this hook depends on an args-substitution behavior that doesn't work in all pre-commit runners (I use Prek).

    As a workaround, I wrote my own local hook to get the expected behavior:

      - repo: local
        hooks:
          - id: commitizen-branch
            name: commitizen check branch
            entry: bash -c 'uv run --quiet cz check --rev-range "$PRE_COMMIT_FROM_REF..$PRE_COMMIT_TO_REF"' --
            language: system
            stages: [ pre-push ]
            pass_filenames: false
            always_run: true
  2. mcsitter commented on Jul 28, 2026

    @mcsitter

    Some of my findings.

    Running against master, commitizen-branch fails with both prek and pre-commit, but differently.

    With prek, PRE_COMMIT_TO_REF is expanded while PRE_COMMIT_FROM_REF remains literal ($PRE_COMMIT_FROM_REF..<sha>).

    With pre-commit, both variables remain literal ($PRE_COMMIT_FROM_REF..$PRE_COMMIT_TO_REF).

    Here is more info regarding the changes to the variables.

    The relevant changes were introduced in these pull requests:

    1. Default commitizen-branch hook arguments changed to use pre-commit variables

    PR: #1815

    Changed:
    args: [--rev-range, origin/HEAD..HEAD]

    to:

    args: [--rev-range, "$PRE_COMMIT_TO_REF $PRE_COMMIT_FROM_REF"]

    This introduced the use of PRE_COMMIT_FROM_REF / PRE_COMMIT_TO_REF in the packaged hook configuration.

    1. commitizen-branch rev-range syntax changed

    PR: #1841

    Changed:

    args: [--rev-range, "$PRE_COMMIT_TO_REF $PRE_COMMIT_FROM_REF"]

    to:

    args: [--rev-range, "$PRE_COMMIT_FROM_REF..$PRE_COMMIT_TO_REF"]

    This changed the hook argument from two space-separated refs to the Git range syntax.

    1. Exit code changed from 3 to 23

    PR: #1941

    This changed Git command execution from shell-based execution to shell=False.

    After this change, the literal argument:

    $PRE_COMMIT_FROM_REF..$PRE_COMMIT_TO_REF

    was passed directly to Git instead of being expanded by the shell.

    The failure changed from:

    - exit code: 3

    to:

    - exit code: 23

    with:

    fatal: ambiguous argument '$PRE_COMMIT_FROM_REF..$PRE_COMMIT_TO_REF': unknown revision or path not in the working tree.

    1. Expansion of environment variables in --rev-range

    PR: #2005

    Added explicit environment variable expansion in cz check --rev-range.

    This restored handling of:

    $PRE_COMMIT_FROM_REF..$PRE_COMMIT_TO_REF

    without using shell expansion.

    Additional detail:

    • Expansion of both variables was added here.
    • Expansion of a single variable can be observed after this change when only one environment variable is available, for example:
      $PRE_COMMIT_FROM_REF..00c7da778d77ffdd2e380415e3fd47bab286bc88

    Of course these PRs are linked, but i tested commits with this script which accepts a ref for commitizen to test the hook behaviour for a given tag or commit.

    #!/usr/bin/env bash
    set -u
    set -o pipefail
    
    REV="${1:?Usage: $0 <commitizen-rev>}"
    
    ROOT=$(mktemp -d)
    REPO="$ROOT/repro"
    REMOTE="$ROOT/remote.git"
    
    echo "Testing Commitizen rev: $REV"
    echo "Temp dir: $ROOT"
    
    mkdir "$REPO"
    cd "$REPO"
    
    uv init >/dev/null
    uv add --dev prek >/dev/null
    
    cat > .pre-commit-config.yaml <<EOF
    default_install_hook_types:
      - pre-push
      - commit-msg
    
    repos:
      - repo: https://github.com/commitizen-tools/commitizen
        rev: $REV
        hooks:
          - id: commitizen
            stages: [commit-msg]
          - id: commitizen-branch
            stages: [pre-push]
    EOF
    
    git init -q
    
    uv run prek install --hook-type pre-push --hook-type commit-msg
    
    git config user.name "Test"
    git config user.email "test@example.com"
    
    git add .
    git commit -m "feat: initial commit"
    
    git branch -M main
    
    git init --bare -q "$REMOTE"
    
    git remote add origin "$REMOTE"
    
    git checkout -b test-commitizen-branch
    
    git commit --allow-empty -m "feat: reproduce issue"
    
    git push -u origin test-commitizen-branch
    

    Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions