Pre-commit ruff-format hook re-stages reformatted files and blocks commits #37

Closed
opened 2026-06-21 16:01:56 +00:00 by Mark · 1 comment
Owner

What this is

The repo's .pre-commit-config.yaml defines a ruff-format hook that
modifies staged files in place. When git commit runs the hook, it
reformats the file and re-stages it, which on next commit attempt is
seen as 'unstaged changes detected' by pre-commit, which then re-runs
the hook, which reformats again, which blocks the commit in an
infinite loop. Manual commits with --no-verify work but bypass
linting.

Reproduction

cd ~/Projects/pc2cad
echo 'x=1' > foo.py
git add foo.py
git commit -m test
# pre-commit: ruff-format re-stages foo.py (x = 1)
# pre-commit: detects 'unstaged changes' (because of re-staging)
# pre-commit: runs ruff-format AGAIN
# loops

Expected

git commit should commit the staged version after running hooks once.

Actual

Pre-commit detects 'unstaged files' (because ruff-format re-staged
them), runs the hook again, which reformats and re-stages, which
triggers the same check. The commit never completes. Manual
git commit --no-verify works but bypasses formatting enforcement.

Environment

  • pre-commit version: per .pre-commit-config.yaml
  • ruff version: per .venv/bin/ruff --version
  • Reproduced on: 2026-06-21 by quickfix-kilo runner

Suggested fix

Configure .pre-commit-config.yaml ruff-format hook with
stages: [manual] or pass_filenames: false so it does not
auto-re-stage, OR add --no-verify to the project's standard commit
workflow, OR pin ruff-format to run only on specific paths that
do not conflict with the work being committed.

Why I'm filing this

quickfix-kilo (the Hermes quickfix pipeline) currently uses
--no-verify as a runner-side workaround for this exact bug. That
bypasses linting in the commit step. The fix should live in the
repo's pre-commit config, not the runner.

Repro logs: see /tmp/quickfix-pc2cad-28.log for the original
failure trace where git commit got stuck in this loop during
the #28 fix.

## What this is The repo's `.pre-commit-config.yaml` defines a `ruff-format` hook that modifies staged files in place. When `git commit` runs the hook, it reformats the file and re-stages it, which on next commit attempt is seen as 'unstaged changes detected' by pre-commit, which then re-runs the hook, which reformats again, which blocks the commit in an infinite loop. Manual commits with `--no-verify` work but bypass linting. ## Reproduction ```bash cd ~/Projects/pc2cad echo 'x=1' > foo.py git add foo.py git commit -m test # pre-commit: ruff-format re-stages foo.py (x = 1) # pre-commit: detects 'unstaged changes' (because of re-staging) # pre-commit: runs ruff-format AGAIN # loops ``` ## Expected `git commit` should commit the staged version after running hooks once. ## Actual Pre-commit detects 'unstaged files' (because ruff-format re-staged them), runs the hook again, which reformats and re-stages, which triggers the same check. The commit never completes. Manual `git commit --no-verify` works but bypasses formatting enforcement. ## Environment - pre-commit version: per `.pre-commit-config.yaml` - ruff version: per `.venv/bin/ruff --version` - Reproduced on: 2026-06-21 by quickfix-kilo runner ## Suggested fix Configure `.pre-commit-config.yaml` `ruff-format` hook with `stages: [manual]` or `pass_filenames: false` so it does not auto-re-stage, OR add `--no-verify` to the project's standard commit workflow, OR pin ruff-format to run only on specific paths that do not conflict with the work being committed. ## Why I'm filing this quickfix-kilo (the Hermes quickfix pipeline) currently uses `--no-verify` as a runner-side workaround for this exact bug. That bypasses linting in the commit step. The fix should live in the repo's pre-commit config, not the runner. Repro logs: see `/tmp/quickfix-pc2cad-28.log` for the original failure trace where `git commit` got stuck in this loop during the #28 fix.
Author
Owner

Auto-triage: needs decompose

Marked triage-approved + needs-decompose. decompose-executor will pick this up and break it into implementable sub-issues.

## Auto-triage: needs decompose Marked `triage-approved` + `needs-decompose`. decompose-executor will pick this up and break it into implementable sub-issues.
Mark 2026-06-21 16:15:05 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/pc2cad#37
No description provided.