# Git-history hotspots

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](https://quality.stereobooster.com/coverage.md).

## The empirical record

- **FixCache** (Kim et al. 2007)[^kim2007] — 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)[^lewis2013]
  — 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)[^rahman2011] — 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)[^tornhill2015] — the
  practitioner-facing book that turned the technique into a
  workflow, with Code Maat as the worked toolchain.

## Tools

| Tool                 | Form                          | Notes                                                                          |
| -------------------- | ----------------------------- | ------------------------------------------------------------------------------ |
| **[Code Maat](https://github.com/adamtornhill/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](https://github.com/src-d/hercules)**         | Go CLI                        | Larger-scope repo-analysis tool; produces churn and coupling reports. |
| **[git-of-theseus](https://github.com/erikbern/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

1. **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.
2. **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.
3. **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.
4. **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.
5. **A ranking locates, and nothing more.**
   [Coverage](https://quality.stereobooster.com/coverage.md) 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](https://quality.stereobooster.com/design-folklore.md)).
- **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](https://quality.stereobooster.com/change-point-detection.md) 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](https://quality.stereobooster.com/maintainability.md) · Quality dimensions
- [Quality dimensions](https://quality.stereobooster.com/quality-dimensions.md) · Quality dimensions
- [Clone detection](https://quality.stereobooster.com/clone-detection.md) · Methods
- [Refactoring practice](https://quality.stereobooster.com/refactoring-practice.md) · Methods
- [The test suite as an object](https://quality.stereobooster.com/test-suite.md) · Methods
- [AI tooling for process methods](https://quality.stereobooster.com/ai-process.md) · AI
- [How AI fits into software quality](https://quality.stereobooster.com/ai.md) · AI

## References

[^kim2007]: Kim, Sunghun, Thomas Zimmermann, E. James Whitehead Jr., and Andreas Zeller. 2007. "[Predicting Faults from Cached History](https://users.soe.ucsc.edu/~ejw/papers/Kim-Predicting.pdf)." *Proceedings of the 29th International Conference on Software Engineering (ICSE '07)*, 489–98. <https://doi.org/10.1109/ICSE.2007.66>.
[^lewis2013]: 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](https://users.soe.ucsc.edu/~ejw/papers/lewis-icse-2013.pdf)." *Proceedings of the 35th International Conference on Software Engineering (ICSE)*. <https://doi.org/10.1109/icse.2013.6606583>.
[^rahman2011]: Rahman, Foyzur, Daryl Posnett, Abram Hindle, Earl Barr, and Premkumar Devanbu. 2011. "[BugCache for Inspections: Hit or Miss?](https://softwareprocess.es/pubs/rahman2011FSE-bugcache.pdf)" *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>.
[^tornhill2015]: Tornhill, Adam. 2015. *[Your Code as a Crime Scene: Use Forensic Techniques to Arrest Defects, Bottlenecks, and Bad Design in Your Programs](https://archive.org/details/yourcodeascrimes0000torn)*. Pragmatic Bookshelf. <https://archive.org/details/yourcodeascrimes0000torn>.

## Acronyms

- ADR — architecture decision record
- KPI — key performance indicator
