Sync with uv: Eliminate Pre-commit Version Drift
Managing tool versions across multiple configuration files creates persistent headaches in Python development. When you upgrade ruff in your pyproject.toml
, you must remember to manually update the pre-commit hook version in .pre-commit-config.yaml
. This version drift causes inconsistent behavior between local development and pre-commit checks.
The sync-with-uv library solves this by automatically synchronizing tool versions between uv.lock
and .pre-commit-config.yaml
.
The Problem
Consider this common scenario:
# pyproject.toml
[dependency-groups]
lint = ["ruff>=0.1.0", "mypy>=1.0.0"]
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.5 # Must manually sync with pyproject.toml
hooks:
- id: ruff
When uv lock --upgrade
updates ruff to 0.1.8, the pre-commit hook stays pinned to 0.1.5. This creates confusing behavior where local checks differ from pre-commit results.
The Solution
sync-with-uv reads locked versions from uv.lock
and updates corresponding tool versions in .pre-commit-config.yaml
. Tools not managed by uv remain unchanged.
Setup requires adding one hook:
repos:
- repo: https://github.com/tsvikas/sync-with-uv
rev: v0.1.0
hooks:
- id: sync-with-uv
The tool runs before other hooks, ensuring automatic version synchronization on every commit.
Why This Matters
Version drift causes several problems:
- Inconsistent behavior: Different versions may have different rules or formatting
- False positives: Pre-commit might catch issues that don’t exist locally
- Maintenance overhead: Manual synchronization is error-prone and forgotten
- CI failures: Mismatched versions cause unexpected pipeline failures
sync-with-uv eliminates these issues by establishing uv.lock
as the single source of truth for tool versions.
For projects using both uv and pre-commit, sync-with-uv offers a clean solution to version management complexity. The result is one less thing to think about in your development workflow.