-
-
Notifications
You must be signed in to change notification settings - Fork 16
Comparing changes
Open a pull request
base repository: commit-check/commit-check
base: v2.13.1
head repository: commit-check/commit-check
compare: v2.13.2
- 4 commits
- 8 files changed
- 2 contributors
Commits on Aug 5, 2026
-
chore: expand imperative verb whitelist and improve validation logic (#…
…527) * fix: recognise 133 more imperative verbs CC003 matches the subject's first word against a fixed list, so a verb missing from it rejects a subject that was written correctly. The contributor then has to reword something that was never wrong, and the only way to learn which words are acceptable is trial and error. Measured against 40,000 git.git subjects — a project that writes strictly imperative subjects, with its area prefixes stripped so only the verb is compared — the list rejected 17.9% of them. This brings that to 10.5%. The additions come from that corpus, filtered by hand to unambiguous verbs: avoid, clarify, teach, factor, free, mention, plug, inline, restore, retire, treat, tighten and the rest. Adverb-led subjects ("always quote the path") and non-verbs were left out — the first are correct English the list cannot represent, and the second would weaken the check. Both spellings of every -ize/-ise verb are now present. The file had sixteen -ize verbs and four -ise ones, so a project writing British English was being told "normalise" is not imperative. Wrong forms still fail, which is the property that matters: "updated the parser", "adding a new flag", "fixes the crash" and "removed the dead code" are covered by a test alongside the recovered words. The remaining 10.5% is the point of the follow-up issue: a list can only ever approximate "is this an English imperative verb". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * test: keep the new imperative cases out of the benchmark suite They assert which subjects are accepted, not how fast the check runs, and marking them adds twelve identical-cost cases to what CodSpeed measures. The companion test for wrong verb forms was already unmarked, so the pair was inconsistent as well. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * test: assert a spelling pair this change actually completed The British-spelling case used serialise, which the file already contained before this change, so it proved nothing about the addition. customise is the useful one: customize was listed and customise was not, which is exactly the half-a-pair bug the sweep was meant to close. Both spellings are now asserted. Reported by CodeRabbit on #527, and correct — verified against the merge base that serialise predates the change while customise does not. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for 1072b87 - Browse repository at this point
Copy the full SHA 1072b87View commit details
Commits on Aug 6, 2026
-
fix: print the display name in compact output, not the config key (#529)
* fix: print the display name in compact output, not the config key The same failing check is named two ways depending on the format: $ commit-check -m --subject-imperative=true --no-banner CC003 subject-imperative check failed ==> docs: revamped the profile $ commit-check -m --subject-imperative=true --compact [FAIL] CC003 subject_imperative: docs: revamped the profile Both are text written for a person, so they should agree. The kebab-case form is the one that agrees with the rules reference, whose headings read `subject-imperative (CC003)` — so a name printed to a terminal can be searched for there verbatim, which is why the default output already converts. Every other human-facing surface in the ecosystem does the same: commit-check-action converts the JSON `check` field before showing it in step logs, job summaries and pull request comments. Compact was the only one left printing the raw key. The JSON output is deliberately unchanged. Its `check` field carries the snake_case key so a consumer can map a failure back to the `cchk.toml` option that controls it, which is what the action relies on. Both call sites now go through one helper rather than one of them open-coding the conversion, which is how they drifted apart to begin with. Refs #528 * refactor: keep one implementation of the check display name Review pointed out that RuleCatalogEntry.name already did the same snake-to-kebab conversion, so the helper added in the previous commit was a second copy and its docstring claim that every text surface goes through it was false. Two copies of the rule this change exists to enforce is the wrong number. The helper moves to rules_catalog rather than the catalog importing it from util. rules_catalog is a pure data module — dataclasses and nothing else — and commit-check-mcp imports it directly, so it should not gain a dependency on a module that pulls in os, sys and subprocess. Pointing the arrow the other way keeps the catalog light and puts the formatter beside the entry whose name property defines the concept. Verified there is now one implementation, that both call sites reach it, and that importing util, rules_catalog, engine and main together raises no cycle.Configuration menu - View commit details
-
Copy full SHA for 7315edf - Browse repository at this point
Copy the full SHA 7315edfView commit details -
docs: refresh the demo recording, and fix a tape that recorded a fals…
…e pass (#530) * docs: refresh the demo recording, and fix a tape that recorded a false pass The GIF predates rule IDs, so it showed neither the CC001/CC201 identifiers nor the docs links that every failure now prints. Three things were wrong with the tape itself, all found by watching the re-recording rather than by reading it: The hidden setup never configured a git identity, so the initial commit failed, the repository was left with no commits at all, and every branch check then passed silently. The old recording showed `commit-check -b` on `user-login` producing no output whatsoever — a failing branch recorded as clean. It recorded in whatever directory it was invoked from, so running it left `user-login` and `feature/user-login` behind in the maintainer's working copy. It now records inside a throwaway repository. The terminal was too narrow for the output, breaking the conventionalcommits URL mid-token. The width is now measured rather than assumed: `tput cols` in the recorder gives 132 columns at 1400px, and the longest line CC001 prints is 131. The glyph advance is 10.26px, not the 9.6px that assuming 0.6em gives you. Two smaller changes: a passing check prints nothing and exits 0, so the two valid scenes reported an empty screen for four seconds — they now echo the result. And `Output` pointed at demo.gif while the header said to run the tape from the repository root, which wrote the file to the wrong directory. CC201's suggestion is 161 columns and still wraps; fitting it would need a 1700px terminal, which is not a demo, it is a tell that the string is too long. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * docs: stop the demo tape from falling back to $HOME, and clean up after it When a command substitution produces nothing, zsh reads `cd $(...)` as a bare `cd` and goes to $HOME. Confirmed rather than assumed: $ zsh -c 'cd $(true); echo $PWD' /root So a failing mktemp would have left the tape running `git init` in a maintainer's home directory. DEMO_REPO is now guarded with ${DEMO_REPO:?}, which aborts the chain instead: $ zsh -c 'DEMO_REPO=$(false) && cd ${DEMO_REPO:?} && echo REACHED' (chain stops, cwd unchanged) The same guard covers the new hidden cleanup, so rm -rf can never be handed a bare path. A full run now leaves zero directories behind under /tmp, checked from a clean slate. Re-recorded so the committed GIF is the one this tape produces. The visible frames are unchanged — both new commands are inside Hide blocks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Configuration menu - View commit details
-
Copy full SHA for e2edc16 - Browse repository at this point
Copy the full SHA e2edc16View commit details
Commits on Aug 7, 2026
-
fix: resolve merge-base refs that exist only on the remote (#532)
* fix: resolve merge-base refs that exist only on the remote CC202 reported "not rebased onto target branch" for a branch that was correctly based on main the whole time — in every CI checkout of a pull request. Two halves, same mistake: exit 128 from git means "could not resolve that name", and both call sites read it as "not an ancestor". _find_target_branch verifies refs/heads/main, falls back to verifying refs/remotes/origin/main, then returns the bare name either way. A pull request checkout has only the remote-tracking ref, so the caller ran git merge-base --is-ancestor main HEAD fatal: Not a valid object name main (exit 128) and the failure was reported as a rebase problem. The remote fallback now returns origin/<name> — the ref that was just verified. Note that writing require_rebase_target = "origin/main" in config is not a workaround: _find_target_branch tries refs/heads/origin/main and refs/remotes/origin/origin/main, finds neither, returns None, and the check silently passes without checking anything. The second half: get_branch_name() falls back to GITHUB_HEAD_REF, so a detached CI checkout reports a branch name that exists on no local ref. Same 128, same misreading. validate() now retries against HEAD — the same commit, always resolvable — and only a real non-zero ancestry answer fails. Measured in a clone shaped like the runner's checkout: _find_target_branch('main') -> 'main' (before fix) git_merge_base('main', 'HEAD') -> 128 git_merge_base('origin/main', 'HEAD') -> 0 The existing tests never caught this because none of them ran the code they named: two patched commit_check.util.git_merge_base while the engine imports the name directly, so the mock never bound and real git ran against whatever checkout pytest was in — one of them passed only because 128 was misread as FAIL. A third built its rule with no regex, so validate() returned PASS before reaching the mocked call (call count: 0). All three now assert against the engine's own reference, and two new tests drive real git in pull-request-shaped clones. Reverting either fix fails its test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * ci: run the checks again after a runner provisioning failure The build job died before reaching any code: GitHub's runner could not download its own actions ("Failed to resolve action download info. Error: Service Unavailable", three attempts). The workflow token is read-only, so a re-run cannot be requested through the API — an empty commit re-triggers everything and disappears in the squash merge. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * fix: check the remote branch before HEAD when resolving merge-base Re-review caught this before merge: the HEAD fallback traded the false failure for a false pass. On a pull_request event the runner checks out GitHub's synthetic merge commit, whose first parent IS the target tip — so is-ancestor(target, HEAD) is true by construction, for every branch, rebased or not. Measured on a diverged branch in that shape: git_merge_base('origin/main', 'feat/work') -> 128 git_merge_base('origin/main', 'HEAD') -> 0 <- wrong git_merge_base('origin/main', 'origin/feat/work') -> 1 <- the truth An unresolvable branch name now resolves through its remote-tracking ref first; HEAD remains only as the last resort, where it still gives a real answer on checkouts whose HEAD is the branch commit itself (push events, or a branch that was never pushed). A new test builds the merge-ref shape with a genuinely diverged branch and asserts FAIL — disabling the origin/<branch> step fails it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * chore: retrigger checks after a stuck workflow queue The CodSpeed run for 47cd595 has sat in "queued" for nine hours after yesterday's GitHub Actions incident and can no longer be cancelled ("Cannot cancel a workflow re-run that has not yet queued"), so its check never reports. CodeQL's Analyze (python) on the same SHA cannot be re-run through the API either — it answers 403 "cannot be retried". An empty commit is the only lever that reaches both: a new head SHA starts fresh check runs for the whole suite. No file changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * fix: resolve the pull request head when merge-base falls back to HEAD Review caught a residual false pass in the fallback chain. When the branch is unresolvable under both its own name and origin/<branch>, the last resort asked about HEAD -- but on a pull_request event HEAD is GitHub's synthetic merge commit, whose first parent IS the target tip, so it passes any branch. Measured in that shape with the remote ref removed, on a branch that is genuinely behind: git_merge_base('origin/main', 'feat/work') -> 128 git_merge_base('origin/main', 'origin/feat/work') -> 128 git_merge_base('origin/main', 'HEAD') -> 0 <- wrong git_merge_base('origin/main', 'HEAD^2') -> 1 <- the truth HEAD's second parent is the pull request head, the commit actually under review, so the fallback now asks about that whenever HEAD is a merge. This answers rather than giving up: where HEAD has a single parent it is the branch commit itself and still answers for itself, so the rebased detached-checkout case keeps passing. Adds git_rev_parse_verify to test for the second parent, and a test that builds the merge-ref shape with no remote ref and asserts FAIL -- restoring the plain HEAD fallback fails it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn * test: share the merge-ref setup between the diverged cases SonarCloud failed the quality gate at 14.2% duplication on new code (limit 3%). The two diverged-branch tests repeated the same twenty lines of setup and the same chdir/patch/validate dance. Extracts _diverged_merge_ref_clone for the shape and _validate_merge_base for the invocation, leaving each test as its distinguishing step plus an assertion. Net 13 lines lighter, and the regression test still fails when the plain HEAD fallback is restored. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U9zFxq8V4qxG4aMzJhGBFn --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>Configuration menu - View commit details
-
Copy full SHA for 98fb97c - Browse repository at this point
Copy the full SHA 98fb97cView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v2.13.1...v2.13.2