commithygiene 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 commithygiene contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,236 @@
1
+ Metadata-Version: 2.4
2
+ Name: commithygiene
3
+ Version: 0.1.0
4
+ Summary: Read-only linter for noisy, AI-generated git commit history
5
+ Author: commithygiene contributors
6
+ License: MIT
7
+ Keywords: git,commits,linter,ai,agent,cli,ci
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Quality Assurance
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Dynamic: license-file
22
+
23
+ # commithygiene
24
+
25
+ <div align="center">
26
+
27
+ **The read-only linter for AI-mangled git history.**
28
+
29
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
30
+ [![Zero dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](#-zero-dependencies)
31
+ [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE)
32
+ [![Tests](https://img.shields.io/badge/tests-13%2F13%20passing-success.svg)](tests/)
33
+
34
+ *AI agents write a lot of commits. Some of them deserve to be squashed before anyone sees them.*
35
+
36
+ </div>
37
+
38
+ ---
39
+
40
+ ## What problem does this solve?
41
+
42
+ Your AI coding agent (or you, at 2 a.m.) just produced this history:
43
+
44
+ ```
45
+ a1b2c3d Update LoginForm.tsx
46
+ d4e5f6 Fix TypeScript error
47
+ g7h8i9 Revert LoginForm.tsx
48
+ j0k1l2 Update LoginForm.tsx again
49
+ m3n4o5 Fix import
50
+ p6q7r8 wip
51
+ s9t0u1 LoginForm complete
52
+ ```
53
+
54
+ Seven commits. One component. **History that is useless for bisect, hostile to review, and embarrassing to merge.**
55
+
56
+ `commithygiene` finds these commits — *before* they hit your branch. It's read-only: it never rewrites history, never stages files, never touches your reflog. It just **reads** and **reports**. You decide what to do.
57
+
58
+ > **AI wrote the code. You're still responsible for the history.**
59
+
60
+ ## Why commithygiene?
61
+
62
+ Every other tool in this space wants to *rewrite* your history:
63
+
64
+ | Tool | Approach | Needs | Can it gate CI? |
65
+ |---|---|---|---|
66
+ | Claude `git-squash` skill | Interactive squash | Claude Code runtime | ❌ Lives in a chat session |
67
+ | `commit-tidy` / `squash-commits` skills | LLM-guided rebase | Claude + context | ❌ |
68
+ | `yawn` | AI *writes new* commit messages | API key | ❌ |
69
+ | `git-shrink` | Group + squash by similarity | Node.js + npm | ⚠️ Rewrites history |
70
+ | **commithygiene** | **Read-only linter with exit codes** | **Just Python 3.10+** | ✅ **Made for CI** |
71
+
72
+ The ecosystem had `prettier` but no `eslint`. `git-cliff` but no `shellcheck`. **commithygiene is the linter** — the thing you put in your pipeline to *catch* noise, not the thing you run interactively to fix it.
73
+
74
+ ## Features
75
+
76
+ - 🔒 **Read-only by design** — `git log` and `git show` only. Zero risk of destroying history.
77
+ - 🪶 **Zero dependencies** — one file, pure Python standard library. No npm, no Rust toolchain, no API key.
78
+ - 🤖 **Knows AI fingerprints** — detects `wip`, `fix typo again`, `revert the revert`, `actually works now`, and other agent churn patterns.
79
+ - 🚦 **CI-ready exit codes** — `0` clean, `1` noise found, `2` error. `--strict` promotes warnings to errors.
80
+ - 📊 **JSON output** — machine-readable for scripts, bots, and dashboards.
81
+ - 📈 **Health reports** — `report` gives you a project-wide noise ratio and verdict.
82
+ - 🐍 **Python 3.10+** — runs anywhere Python runs. Windows, macOS, Linux.
83
+
84
+ ## Quick start
85
+
86
+ ### 1. Drop it in
87
+
88
+ ```bash
89
+ # No install needed — it's a single file.
90
+ curl -O https://raw.githubusercontent.com/DEL8108/commit-hygiene-checker/main/commithygiene.py
91
+ python commithygiene.py check
92
+ ```
93
+
94
+ Or install properly:
95
+
96
+ ```bash
97
+ pip install git+https://github.com/DEL8108/commit-hygiene-checker.git
98
+ commithygiene check
99
+ ```
100
+
101
+ ### 2. Run it on your current branch
102
+
103
+ ```bash
104
+ $ commithygiene check
105
+
106
+ commithygiene — scanned 8 commit(s)
107
+
108
+ ✗ noise-subject 650b5e8c43 noise commit: 'wip'
109
+ ✗ noise-subject 9743088c03 noise commit: 'wip'
110
+ ! churn-subject 562493cd3e possible churn commit: 'fix typo again'
111
+ ! churn-subject 5871f1d5c1 possible churn commit: 'actually works now'
112
+ ! churn-subject a4590d7b47 possible churn commit: 'revert the revert'
113
+ ! trivial-only 4ffd15159e tiny diff touching only trivial files (README.md)
114
+ ```
115
+
116
+ Exit code `1` — your CI just found noise before your reviewer did.
117
+
118
+ ### 3. Gate your PRs
119
+
120
+ ```yaml
121
+ # .github/workflows/hygiene.yml
122
+ name: Commit Hygiene
123
+ on: [pull_request]
124
+ jobs:
125
+ hygiene:
126
+ runs-on: ubuntu-latest
127
+ steps:
128
+ - uses: actions/checkout@v4
129
+ with:
130
+ fetch-depth: 0 # need full history
131
+ - uses: actions/setup-python@v5
132
+ with:
133
+ python-version: "3.12"
134
+ - name: Check commit hygiene
135
+ run: |
136
+ curl -O https://raw.githubusercontent.com/DEL8108/commit-hygiene-checker/main/commithygiene.py
137
+ python commithygiene.py check "${{ github.event.pull_request.base.sha }}..HEAD" --strict
138
+ ```
139
+
140
+ Now every PR with a `wip` or an `actually works now` in it gets flagged **before merge**.
141
+
142
+ ## Usage
143
+
144
+ ### `check` — find noisy commits
145
+
146
+ ```bash
147
+ commithygiene check # scan all of HEAD
148
+ commithygiene check HEAD~20..HEAD # scan the last 20 commits
149
+ commithygiene check main..HEAD # only commits on this branch
150
+ commithygiene check --strict # warnings become errors (exit 1)
151
+ commithygiene check --format json # machine-readable output
152
+ ```
153
+
154
+ ### `report` — project-wide health
155
+
156
+ ```bash
157
+ $ commithygiene report
158
+
159
+ commit hygiene report — HEAD
160
+
161
+ commits : 128
162
+ noise commits : 31 (24%)
163
+ churn commits : 12 (9%)
164
+ verdict : very noisy
165
+ ```
166
+
167
+ ### Exit codes
168
+
169
+ | Code | Meaning |
170
+ |---|---|
171
+ | `0` | Clean — no noise, or only warnings (without `--strict`) |
172
+ | `1` | Noise found — errors, or warnings under `--strict` |
173
+ | `2` | Usage / I/O error (not a git repo, bad range, git missing) |
174
+
175
+ ## What gets flagged
176
+
177
+ | Rule | Severity | Example |
178
+ |---|---|---|
179
+ | `noise-subject` | error | `wip`, `tmp`, `fixup!`, `???`, `initial commit`, `checkpoint` |
180
+ | `churn-subject` | warning | `fix typo again`, `revert the revert`, `actually works now`, `for real this time` |
181
+ | `trivial-only` | warning | a 1-file commit touching only `README.md`, lockfiles, `.gitignore` |
182
+
183
+ Warnings stay warnings unless you pass `--strict` — because sometimes a `revert` is a legitimate, deliberate decision. `commithygiene` errs on the side of *showing* you, not *blocking* you.
184
+
185
+ ## How it works
186
+
187
+ ```
188
+ git log --format=%H <range> # list commits, oldest first
189
+
190
+
191
+ git show --numstat --format=%s <h> # subject + per-file stats per commit
192
+
193
+
194
+ heuristic engine # noise patterns, churn tokens, trivial paths
195
+
196
+
197
+ findings ──► table / json ──► exit code 0/1/2
198
+ ```
199
+
200
+ No git history is modified at any step. The only commands executed are `git log`, `git show`, and `git rev-parse`. You can audit the entire tool in one sitting — it's ~500 lines.
201
+
202
+ ## Why "hygiene"?
203
+
204
+ Because that's what it is. Like flossing, nobody *wants* to think about commit hygiene, but the alternative is worse. The name also means the tool is easily discoverable apart from the squash/rewrite crowd — this is the *prevention* layer, not the *surgery* layer.
205
+
206
+ ## Limitations
207
+
208
+ Being read-only and heuristic-driven means some things are out of scope, on purpose:
209
+
210
+ - **It never rewrites history.** For that, use `git rebase -i`, `git-squash`, or `git-shrink`.
211
+ - **It judges by signals, not semantics.** A `wip` with a giant meaningful diff is still flagged — you know your repo better than the heuristic does.
212
+ - **It doesn't verify build state.** Two commits both labeled `fix` could each be perfectly fine.
213
+ - **No AI, no LLM calls, no telemetry.** It's deterministic. The same input always produces the same output. That's a feature.
214
+
215
+ ## Contributing
216
+
217
+ Found a noise pattern the tool missed? A false positive? Contributions are welcome:
218
+
219
+ 1. Fork and clone the repo.
220
+ 2. Run the tests: `python -m unittest discover -s tests -v`
221
+ 3. Add a test for your pattern in `tests/test_commithygiene.py`.
222
+ 4. Open a PR with a clear description.
223
+
224
+ The whole philosophy is "small, conservative, zero false-positive pressure." New rules need example commits that prove the signal is real.
225
+
226
+ ## License
227
+
228
+ MIT — see [LICENSE](LICENSE). Do whatever you want with it; attribution appreciated.
229
+
230
+ ---
231
+
232
+ <div align="center">
233
+
234
+ **Star it if your agent's commit history has ever made you say "what is this?"** ⭐
235
+
236
+ </div>
@@ -0,0 +1,214 @@
1
+ # commithygiene
2
+
3
+ <div align="center">
4
+
5
+ **The read-only linter for AI-mangled git history.**
6
+
7
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
8
+ [![Zero dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](#-zero-dependencies)
9
+ [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE)
10
+ [![Tests](https://img.shields.io/badge/tests-13%2F13%20passing-success.svg)](tests/)
11
+
12
+ *AI agents write a lot of commits. Some of them deserve to be squashed before anyone sees them.*
13
+
14
+ </div>
15
+
16
+ ---
17
+
18
+ ## What problem does this solve?
19
+
20
+ Your AI coding agent (or you, at 2 a.m.) just produced this history:
21
+
22
+ ```
23
+ a1b2c3d Update LoginForm.tsx
24
+ d4e5f6 Fix TypeScript error
25
+ g7h8i9 Revert LoginForm.tsx
26
+ j0k1l2 Update LoginForm.tsx again
27
+ m3n4o5 Fix import
28
+ p6q7r8 wip
29
+ s9t0u1 LoginForm complete
30
+ ```
31
+
32
+ Seven commits. One component. **History that is useless for bisect, hostile to review, and embarrassing to merge.**
33
+
34
+ `commithygiene` finds these commits — *before* they hit your branch. It's read-only: it never rewrites history, never stages files, never touches your reflog. It just **reads** and **reports**. You decide what to do.
35
+
36
+ > **AI wrote the code. You're still responsible for the history.**
37
+
38
+ ## Why commithygiene?
39
+
40
+ Every other tool in this space wants to *rewrite* your history:
41
+
42
+ | Tool | Approach | Needs | Can it gate CI? |
43
+ |---|---|---|---|
44
+ | Claude `git-squash` skill | Interactive squash | Claude Code runtime | ❌ Lives in a chat session |
45
+ | `commit-tidy` / `squash-commits` skills | LLM-guided rebase | Claude + context | ❌ |
46
+ | `yawn` | AI *writes new* commit messages | API key | ❌ |
47
+ | `git-shrink` | Group + squash by similarity | Node.js + npm | ⚠️ Rewrites history |
48
+ | **commithygiene** | **Read-only linter with exit codes** | **Just Python 3.10+** | ✅ **Made for CI** |
49
+
50
+ The ecosystem had `prettier` but no `eslint`. `git-cliff` but no `shellcheck`. **commithygiene is the linter** — the thing you put in your pipeline to *catch* noise, not the thing you run interactively to fix it.
51
+
52
+ ## Features
53
+
54
+ - 🔒 **Read-only by design** — `git log` and `git show` only. Zero risk of destroying history.
55
+ - 🪶 **Zero dependencies** — one file, pure Python standard library. No npm, no Rust toolchain, no API key.
56
+ - 🤖 **Knows AI fingerprints** — detects `wip`, `fix typo again`, `revert the revert`, `actually works now`, and other agent churn patterns.
57
+ - 🚦 **CI-ready exit codes** — `0` clean, `1` noise found, `2` error. `--strict` promotes warnings to errors.
58
+ - 📊 **JSON output** — machine-readable for scripts, bots, and dashboards.
59
+ - 📈 **Health reports** — `report` gives you a project-wide noise ratio and verdict.
60
+ - 🐍 **Python 3.10+** — runs anywhere Python runs. Windows, macOS, Linux.
61
+
62
+ ## Quick start
63
+
64
+ ### 1. Drop it in
65
+
66
+ ```bash
67
+ # No install needed — it's a single file.
68
+ curl -O https://raw.githubusercontent.com/DEL8108/commit-hygiene-checker/main/commithygiene.py
69
+ python commithygiene.py check
70
+ ```
71
+
72
+ Or install properly:
73
+
74
+ ```bash
75
+ pip install git+https://github.com/DEL8108/commit-hygiene-checker.git
76
+ commithygiene check
77
+ ```
78
+
79
+ ### 2. Run it on your current branch
80
+
81
+ ```bash
82
+ $ commithygiene check
83
+
84
+ commithygiene — scanned 8 commit(s)
85
+
86
+ ✗ noise-subject 650b5e8c43 noise commit: 'wip'
87
+ ✗ noise-subject 9743088c03 noise commit: 'wip'
88
+ ! churn-subject 562493cd3e possible churn commit: 'fix typo again'
89
+ ! churn-subject 5871f1d5c1 possible churn commit: 'actually works now'
90
+ ! churn-subject a4590d7b47 possible churn commit: 'revert the revert'
91
+ ! trivial-only 4ffd15159e tiny diff touching only trivial files (README.md)
92
+ ```
93
+
94
+ Exit code `1` — your CI just found noise before your reviewer did.
95
+
96
+ ### 3. Gate your PRs
97
+
98
+ ```yaml
99
+ # .github/workflows/hygiene.yml
100
+ name: Commit Hygiene
101
+ on: [pull_request]
102
+ jobs:
103
+ hygiene:
104
+ runs-on: ubuntu-latest
105
+ steps:
106
+ - uses: actions/checkout@v4
107
+ with:
108
+ fetch-depth: 0 # need full history
109
+ - uses: actions/setup-python@v5
110
+ with:
111
+ python-version: "3.12"
112
+ - name: Check commit hygiene
113
+ run: |
114
+ curl -O https://raw.githubusercontent.com/DEL8108/commit-hygiene-checker/main/commithygiene.py
115
+ python commithygiene.py check "${{ github.event.pull_request.base.sha }}..HEAD" --strict
116
+ ```
117
+
118
+ Now every PR with a `wip` or an `actually works now` in it gets flagged **before merge**.
119
+
120
+ ## Usage
121
+
122
+ ### `check` — find noisy commits
123
+
124
+ ```bash
125
+ commithygiene check # scan all of HEAD
126
+ commithygiene check HEAD~20..HEAD # scan the last 20 commits
127
+ commithygiene check main..HEAD # only commits on this branch
128
+ commithygiene check --strict # warnings become errors (exit 1)
129
+ commithygiene check --format json # machine-readable output
130
+ ```
131
+
132
+ ### `report` — project-wide health
133
+
134
+ ```bash
135
+ $ commithygiene report
136
+
137
+ commit hygiene report — HEAD
138
+
139
+ commits : 128
140
+ noise commits : 31 (24%)
141
+ churn commits : 12 (9%)
142
+ verdict : very noisy
143
+ ```
144
+
145
+ ### Exit codes
146
+
147
+ | Code | Meaning |
148
+ |---|---|
149
+ | `0` | Clean — no noise, or only warnings (without `--strict`) |
150
+ | `1` | Noise found — errors, or warnings under `--strict` |
151
+ | `2` | Usage / I/O error (not a git repo, bad range, git missing) |
152
+
153
+ ## What gets flagged
154
+
155
+ | Rule | Severity | Example |
156
+ |---|---|---|
157
+ | `noise-subject` | error | `wip`, `tmp`, `fixup!`, `???`, `initial commit`, `checkpoint` |
158
+ | `churn-subject` | warning | `fix typo again`, `revert the revert`, `actually works now`, `for real this time` |
159
+ | `trivial-only` | warning | a 1-file commit touching only `README.md`, lockfiles, `.gitignore` |
160
+
161
+ Warnings stay warnings unless you pass `--strict` — because sometimes a `revert` is a legitimate, deliberate decision. `commithygiene` errs on the side of *showing* you, not *blocking* you.
162
+
163
+ ## How it works
164
+
165
+ ```
166
+ git log --format=%H <range> # list commits, oldest first
167
+
168
+
169
+ git show --numstat --format=%s <h> # subject + per-file stats per commit
170
+
171
+
172
+ heuristic engine # noise patterns, churn tokens, trivial paths
173
+
174
+
175
+ findings ──► table / json ──► exit code 0/1/2
176
+ ```
177
+
178
+ No git history is modified at any step. The only commands executed are `git log`, `git show`, and `git rev-parse`. You can audit the entire tool in one sitting — it's ~500 lines.
179
+
180
+ ## Why "hygiene"?
181
+
182
+ Because that's what it is. Like flossing, nobody *wants* to think about commit hygiene, but the alternative is worse. The name also means the tool is easily discoverable apart from the squash/rewrite crowd — this is the *prevention* layer, not the *surgery* layer.
183
+
184
+ ## Limitations
185
+
186
+ Being read-only and heuristic-driven means some things are out of scope, on purpose:
187
+
188
+ - **It never rewrites history.** For that, use `git rebase -i`, `git-squash`, or `git-shrink`.
189
+ - **It judges by signals, not semantics.** A `wip` with a giant meaningful diff is still flagged — you know your repo better than the heuristic does.
190
+ - **It doesn't verify build state.** Two commits both labeled `fix` could each be perfectly fine.
191
+ - **No AI, no LLM calls, no telemetry.** It's deterministic. The same input always produces the same output. That's a feature.
192
+
193
+ ## Contributing
194
+
195
+ Found a noise pattern the tool missed? A false positive? Contributions are welcome:
196
+
197
+ 1. Fork and clone the repo.
198
+ 2. Run the tests: `python -m unittest discover -s tests -v`
199
+ 3. Add a test for your pattern in `tests/test_commithygiene.py`.
200
+ 4. Open a PR with a clear description.
201
+
202
+ The whole philosophy is "small, conservative, zero false-positive pressure." New rules need example commits that prove the signal is real.
203
+
204
+ ## License
205
+
206
+ MIT — see [LICENSE](LICENSE). Do whatever you want with it; attribution appreciated.
207
+
208
+ ---
209
+
210
+ <div align="center">
211
+
212
+ **Star it if your agent's commit history has ever made you say "what is this?"** ⭐
213
+
214
+ </div>