Incrementally format only changed C/C++ lines with clang-format — works in both local and CI pre-commit contexts
Project description
clang-format-inc
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 viaadditional_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.
Diff mode (show what would change)
hooks:
- id: clang-format-inc
args: [--diff]
Like --check, but also prints a unified diff of every change that would be applied. Useful for PR comment bots or debugging. --check and --diff are mutually exclusive.
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
-p NUM Strip NUM leading path components from diff filenames (default: 1)
--include REGEX Only process files whose path matches this regex
--exclude REGEX Skip files whose path matches this regex
--workers N Number of parallel clang-format processes (default: 1)
Modes (mutually exclusive):
--check Don't modify files; exit non-zero if any file would be reformatted
--diff Don't modify files; print a unified diff of what would change
Notes
Untracked files (not yet added to git) have no history to diff against, so they are formatted in their entirety rather than incrementally. Stage the file with git add first for incremental behaviour.
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file clang_format_inc-0.3.0.tar.gz.
File metadata
- Download URL: clang_format_inc-0.3.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa378623cf030a4febc4f75fadd3aca10f115193ae3beab64e697a43f0da3c47
|
|
| MD5 |
fd7bd02fe71a13150a50611aacfc01e8
|
|
| BLAKE2b-256 |
e688166167080294786cac21e69d1aea23c2ed3ad572f39dd0527122b6378f1d
|
Provenance
The following attestation bundles were made for clang_format_inc-0.3.0.tar.gz:
Publisher:
release.yml on goyaladitya05/clang-format-inc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clang_format_inc-0.3.0.tar.gz -
Subject digest:
aa378623cf030a4febc4f75fadd3aca10f115193ae3beab64e697a43f0da3c47 - Sigstore transparency entry: 1185788406
- Sigstore integration time:
-
Permalink:
goyaladitya05/clang-format-inc@0ff111be564e4e4964961898ab4a9daccef640fe -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/goyaladitya05
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0ff111be564e4e4964961898ab4a9daccef640fe -
Trigger Event:
push
-
Statement type:
File details
Details for the file clang_format_inc-0.3.0-py3-none-any.whl.
File metadata
- Download URL: clang_format_inc-0.3.0-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fbc35f97f441ad094429cb4bd07d367105b646c581a0bc08db1261b18725b9c4
|
|
| MD5 |
d2d48af5af6b4cfe4a0201583b55db13
|
|
| BLAKE2b-256 |
b40369a8fcf381494ec47bb946b139c998c306a791d556ce74028a4aee2738d7
|
Provenance
The following attestation bundles were made for clang_format_inc-0.3.0-py3-none-any.whl:
Publisher:
release.yml on goyaladitya05/clang-format-inc
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
clang_format_inc-0.3.0-py3-none-any.whl -
Subject digest:
fbc35f97f441ad094429cb4bd07d367105b646c581a0bc08db1261b18725b9c4 - Sigstore transparency entry: 1185788413
- Sigstore integration time:
-
Permalink:
goyaladitya05/clang-format-inc@0ff111be564e4e4964961898ab4a9daccef640fe -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/goyaladitya05
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0ff111be564e4e4964961898ab4a9daccef640fe -
Trigger Event:
push
-
Statement type: