Skip to main content

Incrementally format only changed C/C++ lines with clang-format — works in both local and CI pre-commit contexts

Project description

clang-format-inc

CI PyPI version Python versions License: MIT Ruff

Incremental C/C++ formatting as a pre-commit hook — format only the lines you changed.


The problem

Tool Issue
mirrors-clang-format Reformats entire files — breaks diffs in large codebases
git clang-format --staged Works locally, but staging area is empty in CI when pre-commit uses --from-ref/--to-ref

clang-format-inc solves both: it reads the PRE_COMMIT_FROM_REF / PRE_COMMIT_TO_REF environment variables that pre-commit sets in CI mode and falls back to --cached (staged changes) locally.

Inspired by darker, which does the same for Python/Black.


How it works

pre-commit (CI, --from-ref/--to-ref)
  └─ sets PRE_COMMIT_FROM_REF, PRE_COMMIT_TO_REF
      └─ clang-format-inc
          └─ git diff -U0 $FROM_REF $TO_REF -- <files>
              └─ clang-format --lines=<start>:<end> -i <file>  ← only changed lines
pre-commit (local)
  └─ clang-format-inc
      └─ git diff -U0 --cached -- <files>
          └─ clang-format --lines=<start>:<end> -i <file>

The diff is parsed to extract added-line ranges per file. clang-format is called with --lines=start:end for each changed hunk — only touched lines are reformatted.


Requirements

  • Python 3.8+
  • clang-format — installed automatically by pre-commit via additional_dependencies (see below), or specify a custom binary with --binary

Usage as a pre-commit hook

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/goyaladitya05/clang-format-inc
    rev: v0.2.0
    hooks:
      - id: clang-format-inc

clang-format is installed automatically into the hook's virtualenv — no system-wide install needed.

Pin a specific clang-format version

hooks:
  - id: clang-format-inc
    additional_dependencies: ['clang-format==18.1.0']

Check mode (report without fixing)

hooks:
  - id: clang-format-inc
    args: [--check]

With --check, the hook exits non-zero if any changed line would be reformatted, but never modifies files. Useful in CI pipelines where you want to report issues without auto-applying fixes.

Run locally

pre-commit run clang-format-inc --all-files

Run in CI (GitHub Actions example)

- name: Run pre-commit
  run: |
    pre-commit run clang-format-inc \
      --from-ref ${{ github.event.pull_request.base.sha }} \
      --to-ref   ${{ github.event.pull_request.head.sha }}

CLI reference

clang-format-inc [options] [files ...]

Options:
  --binary PATH          Path to clang-format binary (default: clang-format)
  --style STYLE          Formatting style: file, LLVM, Google, etc. (default: file)
  --fallback-style STYLE Style to use when --style=file but no .clang-format found
  --sort-includes        Pass --sort-includes to clang-format
  --check                Don't modify files; exit non-zero if any file would be reformatted
  -p NUM                 Strip NUM leading path components from diff filenames (default: 1)

Install from PyPI

pip install clang-format-inc

Environment variables (set automatically by pre-commit)

Variable When set Value
PRE_COMMIT_FROM_REF CI mode (--from-ref) Base commit SHA
PRE_COMMIT_TO_REF CI mode (--to-ref) Head commit SHA

When both are set, clang-format-inc diffs those two commits. Otherwise it diffs the index (--cached).


License

MIT © Aditya Goyal

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

clang_format_inc-0.2.0.tar.gz (13.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

clang_format_inc-0.2.0-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file clang_format_inc-0.2.0.tar.gz.

File metadata

  • Download URL: clang_format_inc-0.2.0.tar.gz
  • Upload date:
  • Size: 13.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for clang_format_inc-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9d87ade46052b85efe5d1a0a470cdbdf2a407e075327399e04bf0e96ef19f7f6
MD5 0331f80afeae9b05e23e1193d6d0713e
BLAKE2b-256 8de041080258905b2afed4e870361faa856ee6fc653e41ee99bc95a338d6dbb5

See more details on using hashes here.

Provenance

The following attestation bundles were made for clang_format_inc-0.2.0.tar.gz:

Publisher: release.yml on goyaladitya05/clang-format-inc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file clang_format_inc-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for clang_format_inc-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b7dc29e1db61c3698e374f39e7cef972a111e41c9a291f29c8ef8eae79a8912a
MD5 5571e69ea0d18af52895396bd50ea617
BLAKE2b-256 0e510d9a4f213d56ac352b11bfcb89224de26df06d303d095395bc738f400200

See more details on using hashes here.

Provenance

The following attestation bundles were made for clang_format_inc-0.2.0-py3-none-any.whl:

Publisher: release.yml on goyaladitya05/clang-format-inc

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page