A git-history hotspot is a file that changes often and is touched by bug-fix commits. Ranking the codebase by this combined signal points refactoring effort where it has the most leverage.
What the signal measures¶
Two raw quantities from git log:
- Churn — how often a file is modified, weighted by how recently. A file changed twice this week is hotter than one changed twenty times five years ago.
- Bug-fix coupling — the share of those commits whose
messages match a bug-fix pattern (
fix:,bug,hotfix, issue-tracker IDs, etc.). A high-churn file with low bug-fix coupling is just an active file; a high-churn file with high bug-fix coupling is a hotspot.
The product of the two — churn weighted by bug-fix density — is the score the ranking sorts on. The extensions on top of it (change coupling between pairs of files, code-age decay, complexity overlay) are refinements of the same core.
What the signal shows¶
- Where defects concentrate. A fault is likelier in a file that recently had one, and likelier again in the files that change alongside it; of the two, a file's own fix history carries most of the signal. The reasons behind a bug survive the fix that closes it: poor design, hidden state, a missing invariant.
- Where to spend refactoring time. Refactoring a file nobody touches is wasted work. Refactoring the file that gets a bug fix every other sprint pays back the cost quickly.
- Coupling the directory tree hides. Two files that always change together (change coupling) are coupled in the design however far apart they sit in the source tree.
What the signal does not show:
- What the bug is. A hotspot names a file, not a defect; the fix still comes from reading the code.
- Whether the file is bad or just central. A core data model touched by every feature will read as a hotspot even if its design is sound. The signal is suggestive, not diagnostic.
- Anything about untested code. Which lines no test executes is what coverage measures; see Coverage.
The empirical record¶
- FixCache (Kim et al. 2007)1 — a cache of the files most recently touched by fault fixes predicted where the next fault landed, with hit rates of 73%–95% at file level across seven open-source projects and a cache holding 10% of the files.
- Does bug prediction support human developers? (Lewis et al. 2013)2 — Google weighted files by their bug-fix commits, decayed by recency, and surfaced the top-ranked ones to engineers in code review. The flag produced no identifiable change in developer behavior: it named a bug-prone file and said nothing about what to do to it, so a reviewer who saw it had no move to make.
- BugCache for Inspections (Rahman et al. 2011)3 — a replication scoring FixCache as an inspection aid: the cache does hold the bug-denser files, but at an inspection budget of 20% of a system's lines it beat a ranking by count of closed bugs on Apache alone, and there by a small margin.
- Your Code as a Crime Scene (Tornhill 2015)4 — the practitioner-facing book that turned the technique into a workflow, with Code Maat as the worked toolchain.
Tools¶
| Tool | Form | Notes |
|---|---|---|
| Code Maat | Clojure CLI | Reads git log; outputs CSV reports for churn, change coupling, code age. The canonical open-source implementation. |
| CodeScene | Hosted commercial product | From Code Maat's author, pairing the hotspot ranking with a smell-catalog layer on top of it. |
git log --stat |
Plain git |
The minimum-viable form: git log --pretty=format: --name-only \| sort \| uniq -c \| sort -rn \| head -50. Produces a file-change-frequency report in seconds; cross-reference manually with bug-fix commits. |
| hercules | Go CLI | Larger-scope repo-analysis tool; produces churn and coupling reports. |
| git-of-theseus | Python | Plots code-age decay over time; a complementary view, not a hotspot ranker per se. |
How to use the signal well¶
- The first run carries most of the information. A top ten usually names a refactor target the team was already avoiding; later runs return the same files until the code changes.
- A ranking without the bug-fix messages behind it is a list, not an investigation. Which kind of bug keeps recurring in a hot file comes from reading its bug-fix commits, not from its rank.
- Change coupling is a finding about the design, not about one file. A coupled pair belongs in an ADR, or in a refactor that puts both files behind one boundary.
- A ranking is a suggestion, not a target. A hotspot flag is input to a person choosing what to refactor rather than a gate on a change.
- A ranking locates, and nothing more. Coverage and code review say what is wrong in the file it points at, so the three compose rather than substitute for each other.
Folklore-tier uses¶
- Treating the smell-catalog dashboard on top of git history as the signal. SonarQube, Code Climate, and the smell layer of CodeScene try to derive quality judgments from churn + complexity heuristics. The underlying hotspot signal is real; the smell catalog layered on top is folklore-tier (see Design folklore).
- Hotspot score as a quality KPI. Same failure mode as coverage targets: when the number becomes a goal, it stops measuring anything. Engineers move bug-fix commits off the hot file by routing changes through a wrapper.
Related¶
Per-commit signals
Both index by commit, but read different things. Git-history
hotspots read git log metadata (churn
weighted by bug-fix coupling) to rank files by defect risk, before any code
runs. Change-point detection reads
a measured metric such as p99 latency across builds and finds the commit where
it shifted.
Classification¶
- Quality dimensions: Maintainability — prioritizes where maintenance effort should go — it ranks files, not a run's output.
- Area: Long-lived codebases with substantial git history; refactoring prioritization.
Referenced by¶
- Maintainability · Quality dimensions
- Quality dimensions · Quality dimensions
- Clone detection · Methods
- Refactoring practice · Methods
- The test suite as an object · Methods
- AI tooling for process methods · AI
- How AI fits into software quality · AI
References¶
-
Kim, Sunghun, Thomas Zimmermann, E. James Whitehead Jr., and Andreas Zeller. 2007. "Predicting Faults from Cached History." Proceedings of the 29th International Conference on Software Engineering (ICSE '07), 489–98. https://doi.org/10.1109/ICSE.2007.66. ↩
-
Lewis, Chris, Zhongpeng Lin, Caitlin Sadowski, Xiaoyan Zhu, Rong Ou, and E. James Whitehead. 2013. "Does Bug Prediction Support Human Developers? Findings from a Google Case Study." Proceedings of the 35th International Conference on Software Engineering (ICSE). https://doi.org/10.1109/icse.2013.6606583. ↩
-
Rahman, Foyzur, Daryl Posnett, Abram Hindle, Earl Barr, and Premkumar Devanbu. 2011. "BugCache for Inspections: Hit or Miss?" Proceedings of the 19th ACM SIGSOFT Symposium and the 13th European Conference on Foundations of Software Engineering (ESEC/FSE '11), 322–31. https://doi.org/10.1145/2025113.2025157. ↩
-
Tornhill, Adam. 2015. Your Code as a Crime Scene: Use Forensic Techniques to Arrest Defects, Bottlenecks, and Bad Design in Your Programs. Pragmatic Bookshelf. https://archive.org/details/yourcodeascrimes0000torn. ↩