Skip to content

Commit 90888cc

Browse files
committed
coupling
1 parent b53a09f commit 90888cc

1 file changed

Lines changed: 57 additions & 3 deletions

File tree

README.md

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ Flags:
314314
--count-as string count extension as language [e.g. jsp:htm,chead:"C Header" maps extension jsp to html and chead to C Header]
315315
--count-as-pattern stringArray count files matching a path pattern as a new named category backed by a base language [repeatable; pattern is glob by default, prefix with re: for regex; e.g. *_spec.rb:"Ruby Spec":Ruby or re:\.test\.js$:"JavaScript Tests":JavaScript]
316316
--count-ignore set to allow .gitignore and .ignore files to be counted
317+
--coupling render the change-coupling report (file pairs that change together over recent git history)
318+
--coupling-for string blast-radius view: given a file path, show what tends to change with it over recent git history
317319
--currency-symbol string set currency symbol (default "$")
318320
--debug enable debug output
319321
--depth int commit window size for git history reports; 0 means entire history (large repos may be slow) (default 1000)
@@ -835,7 +837,7 @@ LOCOMO is a rough estimator with known limitations:
835837

836838
### Git Insight Reports
837839

838-
In addition to counting the working tree, `scc` can run four git-aware reports over recent commit history. Each is selected by a flag and rendered as `tabular` (default), `csv`, or `json` via `--format`. All four are derived from one in-process walk of the repository - there is no `exec("git")`, so the `git` binary does not need to be on `PATH`.
840+
In addition to counting the working tree, `scc` can run five git-aware reports over recent commit history. Each is selected by a flag and rendered as `tabular` (default), `csv`, or `json` via `--format`. All are derived from one in-process walk of the repository - there is no `exec("git")`, so the `git` binary does not need to be on `PATH`.
839841

840842
> **Note:** these reports are **slower** than a normal `scc` run. They walk the repository history (one diff per commit using pure-Go Myers diff via [go-git](https://github.com/go-git/go-git)) instead of just counting the current working tree. Runtime scales with `--depth` (the commit window size, default `1000`; `0` means entire history). On large repositories with deep history, expect runtimes measured in seconds to minutes rather than the millisecond-scale you get from a plain `scc` run. Use `--depth` to bound the window.
841843
@@ -844,6 +846,7 @@ When no report flag is set, `scc` behaves exactly as today, these flags are stri
844846
| Flag | Report | Answers |
845847
|---|---|---|
846848
| `--hotspots` | Hotspots | Which files are defect-prone - high complexity × high churn. |
849+
| `--coupling` / `--coupling-for FILE` | Change coupling | Which files change together - hidden dependencies and blast radius. |
847850
| `--by-author` | Author rollup | Bus factor - who last-touched the surviving code. |
848851
| `--by-author --timeline` | Author timeline | How each author's activity rises and falls over time. |
849852
| `--timeline` | Languages over time | How the language mix shifts - rewrites, migrations. |
@@ -857,7 +860,7 @@ Shared flags for these reports:
857860
| `-w, --wide` | - | 109-column variant of any report (extra columns where applicable). |
858861
| `--no-fold-authors` | off | Disable the name + email-domain identity folding fallback applied after `.mailmap`. |
859862

860-
`--hotspots` is mutually exclusive with `--by-author` / `--timeline`; combining them is an error. With `--by-author` set, `--timeline` switches from the author rollup to the author timeline. Alone, `--timeline` renders the languages timeline.
863+
Each report is standalone: `--hotspots`, `--coupling` (or `--coupling-for`), and `--by-author` / `--timeline` are mutually exclusive, and combining them is an error. `--coupling-for FILE` implies `--coupling`. With `--by-author` set, `--timeline` switches from the author rollup to the author timeline. Alone, `--timeline` renders the languages timeline.
861864

862865
#### Hotspots - `--hotspots`
863866

@@ -881,6 +884,46 @@ main.go Go 180 44 2,510 8 48.2
881884

882885
Tabular output shows the top files (≈20). `--wide` adds a hotspot bar and an added-lines code-vs-comment split (`+Code%`). `--format csv|json` emits every file with a positive score along with the full per-file detail and window metadata.
883886

887+
#### Change coupling - `--coupling` / `--coupling-for`
888+
889+
Which files tend to change together in the same commit I.E. *temporal* coupling.
890+
Surfaces the "if you edit A you probably need to edit B" relationships. `Shared Commits` is how
891+
many commits touched both files; `Coupling` is the share of commits touching *either* file that
892+
touched *both*, so 100% means they never move apart. Pairs are ranked strongest first,
893+
and only pairs sharing at least 2 commits are reported.
894+
895+
```text
896+
$ scc --coupling
897+
───────────────────────────────────────────────────────────────────────────────
898+
Change Coupling · last 1000 commits · 2019-07-24 → 2026-07-20
899+
───────────────────────────────────────────────────────────────────────────────
900+
File A File B Shared Commits Coupling
901+
───────────────────────────────────────────────────────────────────────────────
902+
languages.json processor/constants.go 196 67.6%
903+
LANGUAGES.md languages.json 166 61.3%
904+
LANGUAGES.md processor/constants.go 152 58.2%
905+
main.go processor/processor.go 65 33.9%
906+
───────────────────────────────────────────────────────────────────────────────
907+
top 15 of 492 pairs · sharing ≥2 commits
908+
───────────────────────────────────────────────────────────────────────────────
909+
```
910+
911+
`--coupling-for FILE` narrows to a single file's and what history says tends to move with it.
912+
913+
```text
914+
$ scc --coupling-for processor/workers.go
915+
───────────────────────────────────────────────────────────────────────────────
916+
Change Coupling · last 1000 commits · 2019-07-24 → 2026-07-20
917+
───────────────────────────────────────────────────────────────────────────────
918+
Related File Shared Commits Coupling
919+
───────────────────────────────────────────────────────────────────────────────
920+
processor/structs.go 27 25.2%
921+
processor/workers_test.go 17 17.7%
922+
processor/processor.go 34 15.7%
923+
main.go 23 13.7%
924+
───────────────────────────────────────────────────────────────────────────────
925+
```
926+
884927
#### Author rollup - `--by-author`
885928

886929
Bus factor and last-toucher attribution. Lines untouched in the window collect under the sentinel `(before window)` so percentages reconcile to 100%.
@@ -1591,7 +1634,7 @@ Add to your `claude_desktop_config.json`:
15911634

15921635
#### Exposed Tools
15931636

1594-
The MCP server exposes two tools:
1637+
The MCP server exposes three tools:
15951638

15961639
**`analyze`** - Count lines of code, comments, blanks and estimate complexity for a project directory or file.
15971640

@@ -1619,6 +1662,17 @@ Results are returned as JSON with per-language breakdown (files, lines, code, co
16191662

16201663
Results are returned as JSON with the history window walked (depth, commit count, date range) and a per-file list (file, language, complexity, commits, lines changed, authors, code/comment churn, and a normalised 0–100 score). Requires `path` to be inside a git repository.
16211664

1665+
**`coupling`** - Report change coupling from a git repository's history: files that historically change together. Has two modes, selected by whether `file` is set. With `file`, returns that file's blast radius - the other files that change together with it. Without `file`, returns the repo-wide all-pairs overview.
1666+
1667+
| Parameter | Type | Required | Description |
1668+
|---|---|---|---|
1669+
| `path` | string | no | Directory inside the git repository to analyze. Defaults to current directory. |
1670+
| `file` | string | no | Target file (as it appears at HEAD). Set it for the per-file blast-radius view; omit it for the repo-wide all-pairs report. |
1671+
| `depth` | number | no | Maximum number of recent commits to walk. Default: `1000`. Set to `0` for unlimited. |
1672+
| `limit` | number | no | Maximum rows to return, strongest first - coupled files in per-file mode, file pairs in all-pairs mode. Default: `50`. Set to `-1` for unlimited. |
1673+
1674+
Results are returned as JSON with the history window walked. With `file`, each partner carries its shared-commit count and the directional probabilities `couple` (given you changed the target, how often the partner follows) and `reverse` (the other direction). Without `file`, each pair carries its shared-commit count and symmetric coupling degree. Requires `path` to be inside a git repository.
1675+
16221676
### Adding/Modifying Languages
16231677

16241678
To add or modify a language you will need to edit the `languages.json` file in the root of the project, and then run `go generate` to build it into the application. You can then `go install` or `go build` as normal to produce the binary with your modifications.

0 commit comments

Comments
 (0)