git-archaeologist 1.1.0 → 1.2.1
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.
- package/LICENSE +21 -0
- package/README.md +27 -17
- package/dist/core/gitParser.d.ts +2 -2
- package/dist/core/gitParser.d.ts.map +1 -1
- package/dist/core/gitParser.js +6 -4
- package/dist/core/gitParser.js.map +1 -1
- package/dist/core/orchestrator.d.ts +1 -1
- package/dist/core/orchestrator.d.ts.map +1 -1
- package/dist/core/orchestrator.js +5 -4
- package/dist/core/orchestrator.js.map +1 -1
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/demo.gif +0 -0
- package/git-arch-report-express.html +0 -513
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sushant Verma
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# git-archaeologist
|
|
2
2
|
|
|
3
|
-
](./preview.png)
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/git-archaeologist)
|
|
6
|
-
[](LICENSE)
|
|
7
|
-
[](https://nodejs.org)
|
|
5
|
+
[](https://www.npmjs.com/package/git-archaeologist) [](LICENSE) [](https://nodejs.org)
|
|
8
6
|
|
|
9
|
-
>
|
|
7
|
+
> Find the most dangerous files in any git repo — before you touch them.
|
|
10
8
|
|
|
11
|
-
[Install](#install)
|
|
9
|
+
[Install](#install) · [Usage](#usage) · [What it finds](#what-it-finds) · [How scoring works](#how-scoring-works)
|
|
12
10
|
|
|
13
11
|
---
|
|
14
12
|
|
|
15
13
|
You inherit a codebase. You touch a file. Three things break that you had no idea were connected.
|
|
16
14
|
|
|
17
|
-
This tool reads your entire git history and
|
|
15
|
+
This tool reads your entire git history and tells you which files are ticking time bombs, who will orphan a whole module when they quit, which files are secretly coupled even though nothing in the code shows it, and who truly owns what right now.
|
|
18
16
|
|
|
19
17
|
## Install
|
|
20
18
|
|
|
@@ -26,20 +24,23 @@ npm install -g git-archaeologist
|
|
|
26
24
|
|
|
27
25
|
```bash
|
|
28
26
|
git-arch analyze /path/to/repo
|
|
29
|
-
git-arch analyze /path/to/repo --
|
|
30
|
-
git-arch
|
|
31
|
-
git-arch analyze /path/to/repo --
|
|
27
|
+
git-arch analyze /path/to/repo --since 90d # only last 90 days of commits
|
|
28
|
+
git-arch analyze /path/to/repo --since 2y # only last 2 years
|
|
29
|
+
git-arch analyze /path/to/repo --since 2024-01-01 # since a specific date
|
|
30
|
+
git-arch analyze /path/to/repo --html # dark-themed interactive report
|
|
31
|
+
git-arch cursed --top 10 # just the danger ranking
|
|
32
|
+
git-arch analyze /path/to/repo --json # pipe into other tools
|
|
32
33
|
```
|
|
33
34
|
|
|
34
35
|
## What it finds
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
Curse score — not just most changed. A file touched 100 times in 6 months by 15 people who never talked scores way higher than one touched 200 times over a decade by the same person. Recency, author chaos, and churn rate combined into one number.
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
Bus factor per folder — not per repo. Knowing the whole repo has bus factor 2 is useless. Knowing lib/ is orphaned the day one person leaves is something you can act on.
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
Implicit coupling — files that always change together in the same commit even though nothing in the code connects them. These are your hidden dependencies.
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
Ownership — who owns the lines alive in HEAD right now, not who created the file or who committed last.
|
|
43
44
|
|
|
44
45
|
## Tested on Express.js
|
|
45
46
|
|
|
@@ -54,15 +55,24 @@ Running git-archaeologist on it takes 3 seconds and finds:
|
|
|
54
55
|
## How scoring works
|
|
55
56
|
|
|
56
57
|
```
|
|
57
|
-
curse_score = changes
|
|
58
|
+
curse_score = changes x log2(authors+1) x exp(-0.5 x age_years) x log2(churn_rate+2)
|
|
58
59
|
```
|
|
59
60
|
|
|
60
|
-
The exponential decay on age
|
|
61
|
+
The exponential decay on age means old chaos that stabilized does not show up. Only files actively dangerous right now.
|
|
61
62
|
|
|
62
63
|
## Requirements
|
|
63
64
|
|
|
64
65
|
Node.js >= 18 and git >= 2.30. Works on Linux, macOS, and Windows (WSL).
|
|
65
66
|
|
|
67
|
+
## Contributing
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone https://github.com/SushantVerma7969/git-archaeologist.git
|
|
71
|
+
cd git-archaeologist
|
|
72
|
+
npm install && npm run build
|
|
73
|
+
node dist/index.js analyze /any/repo
|
|
74
|
+
```
|
|
75
|
+
|
|
66
76
|
## License
|
|
67
77
|
|
|
68
|
-
MIT
|
|
78
|
+
[MIT](LICENSE)
|
package/dist/core/gitParser.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CommitRecord, FileStats } from '../types';
|
|
2
2
|
export declare function validateRepo(repoPath: string): void;
|
|
3
3
|
export declare function getRepoName(repoPath: string): string;
|
|
4
|
-
export declare function getTotalCommitCount(repoPath: string): number;
|
|
5
|
-
export declare function parseCommits(repoPath: string): CommitRecord[];
|
|
4
|
+
export declare function getTotalCommitCount(repoPath: string, since?: string): number;
|
|
5
|
+
export declare function parseCommits(repoPath: string, since?: string): CommitRecord[];
|
|
6
6
|
export declare function buildFileStats(commits: CommitRecord[]): Map<string, FileStats>;
|
|
7
7
|
//# sourceMappingURL=gitParser.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitParser.d.ts","sourceRoot":"","sources":["../../src/core/gitParser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEnD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CASnD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcpD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"gitParser.d.ts","sourceRoot":"","sources":["../../src/core/gitParser.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEnD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CASnD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcpD;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5E;AAYD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CA0C7E;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CA+B9E"}
|
package/dist/core/gitParser.js
CHANGED
|
@@ -68,8 +68,9 @@ function getRepoName(repoPath) {
|
|
|
68
68
|
}
|
|
69
69
|
return path.basename(path.resolve(repoPath));
|
|
70
70
|
}
|
|
71
|
-
function getTotalCommitCount(repoPath) {
|
|
72
|
-
const
|
|
71
|
+
function getTotalCommitCount(repoPath, since) {
|
|
72
|
+
const sinceFlag = since ? ` --after="${since}"` : '';
|
|
73
|
+
const out = (0, child_process_1.execSync)(`git rev-list --count HEAD${sinceFlag}`, {
|
|
73
74
|
cwd: repoPath,
|
|
74
75
|
stdio: 'pipe',
|
|
75
76
|
})
|
|
@@ -86,10 +87,11 @@ function sanitizeFilePath(raw) {
|
|
|
86
87
|
}
|
|
87
88
|
return p;
|
|
88
89
|
}
|
|
89
|
-
function parseCommits(repoPath) {
|
|
90
|
+
function parseCommits(repoPath, since) {
|
|
90
91
|
const DELIMITER = '||GITARCH||';
|
|
91
92
|
const BEGIN_MARKER = 'BEGINCOMMIT' + DELIMITER;
|
|
92
|
-
const
|
|
93
|
+
const sinceFlag = since ? ` --after="${since}"` : '';
|
|
94
|
+
const raw = (0, child_process_1.execSync)(`git log --pretty=format:"${BEGIN_MARKER}%H${DELIMITER}%ae${DELIMITER}%an${DELIMITER}%at" --name-only${sinceFlag}`, { cwd: repoPath, stdio: 'pipe', maxBuffer: 512 * 1024 * 1024 }).toString();
|
|
93
95
|
const commits = [];
|
|
94
96
|
const blocks = raw
|
|
95
97
|
.split(BEGIN_MARKER)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitParser.js","sourceRoot":"","sources":["../../src/core/gitParser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,oCASC;AAED,kCAcC;AAED,
|
|
1
|
+
{"version":3,"file":"gitParser.js","sourceRoot":"","sources":["../../src/core/gitParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAY1C,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAY1C,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAkEvF"}
|
|
@@ -9,16 +9,17 @@ const gitParser_1 = require("./gitParser");
|
|
|
9
9
|
const curseScorer_1 = require("../analyzers/curseScorer");
|
|
10
10
|
const ownershipAnalyzer_1 = require("../analyzers/ownershipAnalyzer");
|
|
11
11
|
const busFactorAnalyzer_1 = require("../analyzers/busFactorAnalyzer");
|
|
12
|
-
async function analyze(repoPath) {
|
|
12
|
+
async function analyze(repoPath, since) {
|
|
13
13
|
const spinner = (0, ora_1.default)({ text: 'Validating repository...', color: 'magenta' }).start();
|
|
14
14
|
try {
|
|
15
15
|
// Step 1 — validate
|
|
16
16
|
(0, gitParser_1.validateRepo)(repoPath);
|
|
17
17
|
const repoName = (0, gitParser_1.getRepoName)(repoPath);
|
|
18
|
-
const totalCommits = (0, gitParser_1.getTotalCommitCount)(repoPath);
|
|
19
|
-
|
|
18
|
+
const totalCommits = (0, gitParser_1.getTotalCommitCount)(repoPath, since);
|
|
19
|
+
const sinceLabel = since ? ` (since ${since})` : '';
|
|
20
|
+
spinner.text = `Parsing ${totalCommits.toLocaleString()} commits in ${repoName}${sinceLabel}...`;
|
|
20
21
|
// Step 2 — parse all commits
|
|
21
|
-
const commits = (0, gitParser_1.parseCommits)(repoPath);
|
|
22
|
+
const commits = (0, gitParser_1.parseCommits)(repoPath, since);
|
|
22
23
|
spinner.text = 'Building file statistics...';
|
|
23
24
|
// Step 3 — build per-file stats
|
|
24
25
|
const fileStats = (0, gitParser_1.buildFileStats)(commits);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":";;;;;AAaA,
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/core/orchestrator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -43,22 +43,42 @@ const path = __importStar(require("path"));
|
|
|
43
43
|
const orchestrator_1 = require("./core/orchestrator");
|
|
44
44
|
const terminalRenderer_1 = require("./output/terminalRenderer");
|
|
45
45
|
const htmlReport_1 = require("./output/htmlReport");
|
|
46
|
+
function parseSince(input) {
|
|
47
|
+
// Accept: 90d, 30days, 6months, 1year, or ISO date like 2024-01-01
|
|
48
|
+
const match = input.match(/^(\d+)\s*(d|day|days|m|month|months|y|year|years)$/i);
|
|
49
|
+
if (match) {
|
|
50
|
+
const n = parseInt(match[1], 10);
|
|
51
|
+
const unit = match[2].toLowerCase();
|
|
52
|
+
const date = new Date();
|
|
53
|
+
if (unit.startsWith('d'))
|
|
54
|
+
date.setDate(date.getDate() - n);
|
|
55
|
+
else if (unit.startsWith('m'))
|
|
56
|
+
date.setMonth(date.getMonth() - n);
|
|
57
|
+
else if (unit.startsWith('y'))
|
|
58
|
+
date.setFullYear(date.getFullYear() - n);
|
|
59
|
+
return date.toISOString().split('T')[0];
|
|
60
|
+
}
|
|
61
|
+
// Already a date string
|
|
62
|
+
return input;
|
|
63
|
+
}
|
|
46
64
|
const program = new commander_1.Command();
|
|
47
65
|
program
|
|
48
66
|
.name('git-arch')
|
|
49
67
|
.description(chalk_1.default.hex('#A78BFA')('⛏ Git Archaeologist') +
|
|
50
68
|
' — uncover history, ownership & tech debt in any git repo')
|
|
51
|
-
.version('1.
|
|
69
|
+
.version('1.1.0');
|
|
52
70
|
program
|
|
53
71
|
.command('analyze [repoPath]')
|
|
54
72
|
.alias('a')
|
|
55
73
|
.description('Analyze a git repository and print the full report')
|
|
56
74
|
.option('-j, --json', 'Output raw JSON instead of the terminal report')
|
|
57
75
|
.option('-H, --html [outputFile]', 'Generate an HTML report file')
|
|
76
|
+
.option('-s, --since <date>', 'Only analyze commits after this date (e.g. 90d, 2024-01-01, 6months)')
|
|
58
77
|
.action(async (repoPath, options) => {
|
|
59
78
|
const resolvedPath = path.resolve(repoPath ?? '.');
|
|
79
|
+
const since = options.since ? parseSince(options.since) : undefined;
|
|
60
80
|
try {
|
|
61
|
-
const result = await (0, orchestrator_1.analyze)(resolvedPath);
|
|
81
|
+
const result = await (0, orchestrator_1.analyze)(resolvedPath, since);
|
|
62
82
|
if (options.json) {
|
|
63
83
|
const serializable = {
|
|
64
84
|
...result,
|
|
@@ -114,7 +134,7 @@ program
|
|
|
114
134
|
.action(async () => {
|
|
115
135
|
const resolvedPath = path.resolve('.');
|
|
116
136
|
try {
|
|
117
|
-
const result = await (0, orchestrator_1.analyze)(resolvedPath);
|
|
137
|
+
const result = await (0, orchestrator_1.analyze)(resolvedPath, undefined);
|
|
118
138
|
(0, terminalRenderer_1.renderReport)(result);
|
|
119
139
|
}
|
|
120
140
|
catch (err) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,yCAAoC;AACpC,kDAA0B;AAC1B,2CAA6B;AAE7B,sDAA8C;AAC9C,gEAAyD;AACzD,oDAAyD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-archaeologist",
|
|
3
|
-
"version": "1.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.2.1",
|
|
4
|
+
"description": "Find the most dangerous files in any git repo — curse scores, bus factor, hidden coupling",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"git-arch": "dist/index.js"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"tech-debt",
|
|
19
19
|
"analytics"
|
|
20
20
|
],
|
|
21
|
-
"author": "
|
|
21
|
+
"author": "Sushant Verma",
|
|
22
22
|
"license": "MIT",
|
|
23
23
|
"type": "commonjs",
|
|
24
24
|
"devDependencies": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"homepage": "https://github.com/SushantVerma7969/git-archaeologist",
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|
|
38
|
-
"url": "https://github.com/SushantVerma7969/git-archaeologist.git"
|
|
38
|
+
"url": "git+https://github.com/SushantVerma7969/git-archaeologist.git"
|
|
39
39
|
},
|
|
40
40
|
"bugs": {
|
|
41
41
|
"url": "https://github.com/SushantVerma7969/git-archaeologist/issues"
|
package/demo.gif
DELETED
|
Binary file
|
|
@@ -1,513 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8"/>
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
6
|
-
<title>⛏ Git Archaeologist — express</title>
|
|
7
|
-
<style>
|
|
8
|
-
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
9
|
-
:root {
|
|
10
|
-
--bg: #0f1117; --surface: #1a1d27; --border: #2a2d3a;
|
|
11
|
-
--text: #e2e8f0; --muted: #64748b; --accent: #a78bfa;
|
|
12
|
-
}
|
|
13
|
-
body { background: var(--bg); color: var(--text); font-family: 'Inter', system-ui, sans-serif; font-size: 14px; line-height: 1.6; }
|
|
14
|
-
header { background: var(--surface); border-bottom: 1px solid var(--border); padding: 24px 40px; display: flex; align-items: center; gap: 16px; }
|
|
15
|
-
header h1 { font-size: 20px; font-weight: 600; color: var(--accent); }
|
|
16
|
-
header p { color: var(--muted); font-size: 13px; }
|
|
17
|
-
.stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px; padding: 32px 40px 0; }
|
|
18
|
-
.stat-card { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 16px 20px; }
|
|
19
|
-
.stat-card .label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin-bottom: 6px; }
|
|
20
|
-
.stat-card .value { font-size: 28px; font-weight: 700; color: var(--accent); }
|
|
21
|
-
.stat-card .sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
|
|
22
|
-
main { padding: 32px 40px; display: flex; flex-direction: column; gap: 40px; }
|
|
23
|
-
section h2 { font-size: 15px; font-weight: 600; color: var(--accent); margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
|
|
24
|
-
table { width: 100%; border-collapse: collapse; background: var(--surface); border-radius: 10px; overflow: hidden; border: 1px solid var(--border); }
|
|
25
|
-
th { background: #12151f; color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .05em; padding: 10px 14px; text-align: left; font-weight: 500; }
|
|
26
|
-
td { padding: 10px 14px; border-top: 1px solid var(--border); vertical-align: middle; }
|
|
27
|
-
tr:hover td { background: #1e2130; }
|
|
28
|
-
.rank { color: var(--muted); font-size: 12px; width: 40px; }
|
|
29
|
-
.filepath { font-family: 'JetBrains Mono', 'Fira Code', monospace; font-size: 12px; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
30
|
-
.muted { color: var(--muted); font-size: 12px; }
|
|
31
|
-
.badge { display: inline-block; padding: 2px 10px; border-radius: 20px; font-size: 12px; font-weight: 600; color: #0f1117; }
|
|
32
|
-
footer { text-align: center; padding: 32px; color: var(--muted); font-size: 12px; border-top: 1px solid var(--border); }
|
|
33
|
-
</style>
|
|
34
|
-
</head>
|
|
35
|
-
<body>
|
|
36
|
-
<header>
|
|
37
|
-
<div>
|
|
38
|
-
<h1>⛏ Git Archaeologist</h1>
|
|
39
|
-
<p>express · 1,716 commits · 2014-01-04 → 2026-05-17 · analyzed 3/6/2026, 12:34:32 am</p>
|
|
40
|
-
</div>
|
|
41
|
-
</header>
|
|
42
|
-
|
|
43
|
-
<div class="stats-grid">
|
|
44
|
-
<div class="stat-card"><div class="label">Total Commits</div><div class="value">1,716</div></div>
|
|
45
|
-
<div class="stat-card"><div class="label">Files Tracked</div><div class="value">312</div></div>
|
|
46
|
-
<div class="stat-card"><div class="label">Contributors</div><div class="value">230</div></div>
|
|
47
|
-
<div class="stat-card"><div class="label">Cursed Files</div><div class="value" style="color:#f87171">20</div><div class="sub">top instability</div></div>
|
|
48
|
-
<div class="stat-card"><div class="label">Bus Factor 1</div><div class="value" style="color:#f87171">7</div><div class="sub">single-owner modules</div></div>
|
|
49
|
-
<div class="stat-card"><div class="label">Coupled Pairs</div><div class="value" style="color:#fbbf24">30</div><div class="sub">implicit links</div></div>
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
<main>
|
|
53
|
-
<section>
|
|
54
|
-
<h2>💀 Cursed Files — highest instability score</h2>
|
|
55
|
-
<table>
|
|
56
|
-
<thead><tr><th>#</th><th>File</th><th>Score</th><th>Changes</th><th>Authors</th><th>Why</th></tr></thead>
|
|
57
|
-
<tbody>
|
|
58
|
-
<tr>
|
|
59
|
-
<td class="rank">1</td>
|
|
60
|
-
<td class="filepath" title="History.md">History.md</td>
|
|
61
|
-
<td><span class="badge" style="background:#f87171">30765.0</span></td>
|
|
62
|
-
<td>827</td>
|
|
63
|
-
<td>78</td>
|
|
64
|
-
<td class="muted">Changed 827 times, Touched by 78 different authors, High churn rate (69x/year), Modified very recently</td>
|
|
65
|
-
</tr>
|
|
66
|
-
<tr>
|
|
67
|
-
<td class="rank">2</td>
|
|
68
|
-
<td class="filepath" title="package.json">package.json</td>
|
|
69
|
-
<td><span class="badge" style="background:#f87171">28137.6</span></td>
|
|
70
|
-
<td>861</td>
|
|
71
|
-
<td>41</td>
|
|
72
|
-
<td class="muted">Changed 861 times, Touched by 41 different authors, High churn rate (71x/year), Modified very recently</td>
|
|
73
|
-
</tr>
|
|
74
|
-
<tr>
|
|
75
|
-
<td class="rank">3</td>
|
|
76
|
-
<td class="filepath" title="lib/response.js">lib/response.js</td>
|
|
77
|
-
<td><span class="badge" style="background:#f87171">2261.1</span></td>
|
|
78
|
-
<td>128</td>
|
|
79
|
-
<td>53</td>
|
|
80
|
-
<td class="muted">Changed 128 times, Touched by 53 different authors, Modified very recently</td>
|
|
81
|
-
</tr>
|
|
82
|
-
<tr>
|
|
83
|
-
<td class="rank">4</td>
|
|
84
|
-
<td class="filepath" title=".github/workflows/ci.yml">.github/workflows/ci.yml</td>
|
|
85
|
-
<td><span class="badge" style="background:#f87171">1567.1</span></td>
|
|
86
|
-
<td>94</td>
|
|
87
|
-
<td>16</td>
|
|
88
|
-
<td class="muted">Changed 94 times, Touched by 16 different authors, Modified very recently</td>
|
|
89
|
-
</tr>
|
|
90
|
-
<tr>
|
|
91
|
-
<td class="rank">5</td>
|
|
92
|
-
<td class="filepath" title="Readme.md">Readme.md</td>
|
|
93
|
-
<td><span class="badge" style="background:#f87171">1190.8</span></td>
|
|
94
|
-
<td>79</td>
|
|
95
|
-
<td>37</td>
|
|
96
|
-
<td class="muted">Changed 79 times, Touched by 37 different authors, Modified very recently</td>
|
|
97
|
-
</tr>
|
|
98
|
-
<tr>
|
|
99
|
-
<td class="rank">6</td>
|
|
100
|
-
<td class="filepath" title="lib/application.js">lib/application.js</td>
|
|
101
|
-
<td><span class="badge" style="background:#fbbf24">614.2</span></td>
|
|
102
|
-
<td>58</td>
|
|
103
|
-
<td>22</td>
|
|
104
|
-
<td class="muted">Changed 58 times, Touched by 22 different authors, Modified very recently</td>
|
|
105
|
-
</tr>
|
|
106
|
-
<tr>
|
|
107
|
-
<td class="rank">7</td>
|
|
108
|
-
<td class="filepath" title="appveyor.yml">appveyor.yml</td>
|
|
109
|
-
<td><span class="badge" style="background:#fbbf24">468.8</span></td>
|
|
110
|
-
<td>103</td>
|
|
111
|
-
<td>10</td>
|
|
112
|
-
<td class="muted">Changed 103 times, Touched by 10 different authors</td>
|
|
113
|
-
</tr>
|
|
114
|
-
<tr>
|
|
115
|
-
<td class="rank">8</td>
|
|
116
|
-
<td class="filepath" title="lib/request.js">lib/request.js</td>
|
|
117
|
-
<td><span class="badge" style="background:#fbbf24">420.1</span></td>
|
|
118
|
-
<td>47</td>
|
|
119
|
-
<td>17</td>
|
|
120
|
-
<td class="muted">Touched by 17 different authors, Modified very recently</td>
|
|
121
|
-
</tr>
|
|
122
|
-
<tr>
|
|
123
|
-
<td class="rank">9</td>
|
|
124
|
-
<td class="filepath" title="lib/utils.js">lib/utils.js</td>
|
|
125
|
-
<td><span class="badge" style="background:#fbbf24">410.4</span></td>
|
|
126
|
-
<td>47</td>
|
|
127
|
-
<td>19</td>
|
|
128
|
-
<td class="muted">Touched by 19 different authors</td>
|
|
129
|
-
</tr>
|
|
130
|
-
<tr>
|
|
131
|
-
<td class="rank">10</td>
|
|
132
|
-
<td class="filepath" title="test/app.router.js">test/app.router.js</td>
|
|
133
|
-
<td><span class="badge" style="background:#34d399">306.5</span></td>
|
|
134
|
-
<td>49</td>
|
|
135
|
-
<td>16</td>
|
|
136
|
-
<td class="muted">Touched by 16 different authors</td>
|
|
137
|
-
</tr>
|
|
138
|
-
<tr>
|
|
139
|
-
<td class="rank">11</td>
|
|
140
|
-
<td class="filepath" title=".github/workflows/legacy.yml">.github/workflows/legacy.yml</td>
|
|
141
|
-
<td><span class="badge" style="background:#34d399">305.8</span></td>
|
|
142
|
-
<td>29</td>
|
|
143
|
-
<td>5</td>
|
|
144
|
-
<td class="muted">Modified very recently</td>
|
|
145
|
-
</tr>
|
|
146
|
-
<tr>
|
|
147
|
-
<td class="rank">12</td>
|
|
148
|
-
<td class="filepath" title=".github/workflows/scorecard.yml">.github/workflows/scorecard.yml</td>
|
|
149
|
-
<td><span class="badge" style="background:#34d399">247.7</span></td>
|
|
150
|
-
<td>28</td>
|
|
151
|
-
<td>3</td>
|
|
152
|
-
<td class="muted">High churn rate (21x/year), Modified very recently</td>
|
|
153
|
-
</tr>
|
|
154
|
-
<tr>
|
|
155
|
-
<td class="rank">13</td>
|
|
156
|
-
<td class="filepath" title="test/res.sendFile.js">test/res.sendFile.js</td>
|
|
157
|
-
<td><span class="badge" style="background:#34d399">231.2</span></td>
|
|
158
|
-
<td>39</td>
|
|
159
|
-
<td>13</td>
|
|
160
|
-
<td class="muted">Touched by 13 different authors</td>
|
|
161
|
-
</tr>
|
|
162
|
-
<tr>
|
|
163
|
-
<td class="rank">14</td>
|
|
164
|
-
<td class="filepath" title="test/res.send.js">test/res.send.js</td>
|
|
165
|
-
<td><span class="badge" style="background:#34d399">222.8</span></td>
|
|
166
|
-
<td>37</td>
|
|
167
|
-
<td>15</td>
|
|
168
|
-
<td class="muted">Touched by 15 different authors</td>
|
|
169
|
-
</tr>
|
|
170
|
-
<tr>
|
|
171
|
-
<td class="rank">15</td>
|
|
172
|
-
<td class="filepath" title=".github/workflows/codeql.yml">.github/workflows/codeql.yml</td>
|
|
173
|
-
<td><span class="badge" style="background:#34d399">215.5</span></td>
|
|
174
|
-
<td>23</td>
|
|
175
|
-
<td>5</td>
|
|
176
|
-
<td class="muted">Modified very recently</td>
|
|
177
|
-
</tr>
|
|
178
|
-
<tr>
|
|
179
|
-
<td class="rank">16</td>
|
|
180
|
-
<td class="filepath" title="Contributing.md">Contributing.md</td>
|
|
181
|
-
<td><span class="badge" style="background:#34d399">187.3</span></td>
|
|
182
|
-
<td>33</td>
|
|
183
|
-
<td>15</td>
|
|
184
|
-
<td class="muted">Touched by 15 different authors</td>
|
|
185
|
-
</tr>
|
|
186
|
-
<tr>
|
|
187
|
-
<td class="rank">17</td>
|
|
188
|
-
<td class="filepath" title="test/utils.js">test/utils.js</td>
|
|
189
|
-
<td><span class="badge" style="background:#34d399">174.6</span></td>
|
|
190
|
-
<td>28</td>
|
|
191
|
-
<td>10</td>
|
|
192
|
-
<td class="muted">Touched by 10 different authors, Modified very recently</td>
|
|
193
|
-
</tr>
|
|
194
|
-
<tr>
|
|
195
|
-
<td class="rank">18</td>
|
|
196
|
-
<td class="filepath" title="test/Router.js">test/Router.js</td>
|
|
197
|
-
<td><span class="badge" style="background:#34d399">130.5</span></td>
|
|
198
|
-
<td>32</td>
|
|
199
|
-
<td>11</td>
|
|
200
|
-
<td class="muted">Touched by 11 different authors</td>
|
|
201
|
-
</tr>
|
|
202
|
-
<tr>
|
|
203
|
-
<td class="rank">19</td>
|
|
204
|
-
<td class="filepath" title="lib/router/index.js">lib/router/index.js</td>
|
|
205
|
-
<td><span class="badge" style="background:#34d399">127.7</span></td>
|
|
206
|
-
<td>56</td>
|
|
207
|
-
<td>14</td>
|
|
208
|
-
<td class="muted">Changed 56 times, Touched by 14 different authors</td>
|
|
209
|
-
</tr>
|
|
210
|
-
<tr>
|
|
211
|
-
<td class="rank">20</td>
|
|
212
|
-
<td class="filepath" title="test/res.jsonp.js">test/res.jsonp.js</td>
|
|
213
|
-
<td><span class="badge" style="background:#34d399">114.9</span></td>
|
|
214
|
-
<td>21</td>
|
|
215
|
-
<td>9</td>
|
|
216
|
-
<td class="muted">Touched by 9 different authors, Modified very recently</td>
|
|
217
|
-
</tr></tbody>
|
|
218
|
-
</table>
|
|
219
|
-
</section>
|
|
220
|
-
|
|
221
|
-
<section>
|
|
222
|
-
<h2>🚌 Bus Factor — single points of failure</h2>
|
|
223
|
-
<table>
|
|
224
|
-
<thead><tr><th>Module</th><th>Bus Factor</th><th>Files</th><th>Key People</th><th>Risk</th></tr></thead>
|
|
225
|
-
<tbody>
|
|
226
|
-
<tr>
|
|
227
|
-
<td>(root)</td>
|
|
228
|
-
<td><span class="badge" style="background:#f87171">1</span></td>
|
|
229
|
-
<td>0</td>
|
|
230
|
-
<td>Douglas Christopher Wilson</td>
|
|
231
|
-
<td class="muted"> Single point of failure — only Douglas Christopher Wilson owns this module</td>
|
|
232
|
-
</tr>
|
|
233
|
-
<tr>
|
|
234
|
-
<td>examples</td>
|
|
235
|
-
<td><span class="badge" style="background:#f87171">1</span></td>
|
|
236
|
-
<td>127</td>
|
|
237
|
-
<td>Douglas Christopher Wilson</td>
|
|
238
|
-
<td class="muted"> Single point of failure — only Douglas Christopher Wilson owns this module</td>
|
|
239
|
-
</tr>
|
|
240
|
-
<tr>
|
|
241
|
-
<td>test</td>
|
|
242
|
-
<td><span class="badge" style="background:#f87171">1</span></td>
|
|
243
|
-
<td>133</td>
|
|
244
|
-
<td>Douglas Christopher Wilson</td>
|
|
245
|
-
<td class="muted"> Single point of failure — only Douglas Christopher Wilson owns this module</td>
|
|
246
|
-
</tr>
|
|
247
|
-
<tr>
|
|
248
|
-
<td>lib</td>
|
|
249
|
-
<td><span class="badge" style="background:#f87171">1</span></td>
|
|
250
|
-
<td>13</td>
|
|
251
|
-
<td>Douglas Christopher Wilson</td>
|
|
252
|
-
<td class="muted"> Single point of failure — only Douglas Christopher Wilson owns this module</td>
|
|
253
|
-
</tr>
|
|
254
|
-
<tr>
|
|
255
|
-
<td>benchmarks</td>
|
|
256
|
-
<td><span class="badge" style="background:#f87171">1</span></td>
|
|
257
|
-
<td>4</td>
|
|
258
|
-
<td>Douglas Christopher Wilson</td>
|
|
259
|
-
<td class="muted"> Single point of failure — only Douglas Christopher Wilson owns this module</td>
|
|
260
|
-
</tr>
|
|
261
|
-
<tr>
|
|
262
|
-
<td>bin</td>
|
|
263
|
-
<td><span class="badge" style="background:#f87171">1</span></td>
|
|
264
|
-
<td>1</td>
|
|
265
|
-
<td>Douglas Christopher Wilson</td>
|
|
266
|
-
<td class="muted"> Single point of failure — only Douglas Christopher Wilson owns this module</td>
|
|
267
|
-
</tr>
|
|
268
|
-
<tr>
|
|
269
|
-
<td>support</td>
|
|
270
|
-
<td><span class="badge" style="background:#f87171">1</span></td>
|
|
271
|
-
<td>3</td>
|
|
272
|
-
<td>Douglas Christopher Wilson</td>
|
|
273
|
-
<td class="muted"> Single point of failure — only Douglas Christopher Wilson owns this module</td>
|
|
274
|
-
</tr>
|
|
275
|
-
<tr>
|
|
276
|
-
<td>.github</td>
|
|
277
|
-
<td><span class="badge" style="background:#fbbf24">2</span></td>
|
|
278
|
-
<td>7</td>
|
|
279
|
-
<td>dependabot[bot], Douglas Christopher Wilson</td>
|
|
280
|
-
<td class="muted"> High risk — only 2 people understand this module</td>
|
|
281
|
-
</tr></tbody>
|
|
282
|
-
</table>
|
|
283
|
-
</section>
|
|
284
|
-
|
|
285
|
-
<section>
|
|
286
|
-
<h2>👑 Ownership — who truly owns each file</h2>
|
|
287
|
-
<table>
|
|
288
|
-
<thead><tr><th>File</th><th>Owner</th><th>Ownership</th><th>Other Contributors</th></tr></thead>
|
|
289
|
-
<tbody>
|
|
290
|
-
<tr>
|
|
291
|
-
<td class="filepath" title=".github/dependabot.yml">.github/dependabot.yml</td>
|
|
292
|
-
<td>Sebastian Beltran</td>
|
|
293
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
294
|
-
<td class="muted">—</td>
|
|
295
|
-
</tr>
|
|
296
|
-
<tr>
|
|
297
|
-
<td class="filepath" title=".github/workflows/dependabot.yml">.github/workflows/dependabot.yml</td>
|
|
298
|
-
<td>Ulises Gascon</td>
|
|
299
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
300
|
-
<td class="muted">—</td>
|
|
301
|
-
</tr>
|
|
302
|
-
<tr>
|
|
303
|
-
<td class="filepath" title=".github/workflows/iojs.yml">.github/workflows/iojs.yml</td>
|
|
304
|
-
<td>Jon Church</td>
|
|
305
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
306
|
-
<td class="muted">—</td>
|
|
307
|
-
</tr>
|
|
308
|
-
<tr>
|
|
309
|
-
<td class="filepath" title="test/mocha.opts">test/mocha.opts</td>
|
|
310
|
-
<td>Douglas Christopher Wilson</td>
|
|
311
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
312
|
-
<td class="muted">—</td>
|
|
313
|
-
</tr>
|
|
314
|
-
<tr>
|
|
315
|
-
<td class="filepath" title="test/req.baseUrl.js">test/req.baseUrl.js</td>
|
|
316
|
-
<td>Douglas Christopher Wilson</td>
|
|
317
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
318
|
-
<td class="muted">—</td>
|
|
319
|
-
</tr>
|
|
320
|
-
<tr>
|
|
321
|
-
<td class="filepath" title="test/req.range.js">test/req.range.js</td>
|
|
322
|
-
<td>Douglas Christopher Wilson</td>
|
|
323
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
324
|
-
<td class="muted">—</td>
|
|
325
|
-
</tr>
|
|
326
|
-
<tr>
|
|
327
|
-
<td class="filepath" title="test/res.get.js">test/res.get.js</td>
|
|
328
|
-
<td>Douglas Christopher Wilson</td>
|
|
329
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
330
|
-
<td class="muted">—</td>
|
|
331
|
-
</tr>
|
|
332
|
-
<tr>
|
|
333
|
-
<td class="filepath" title="examples/content-negotiation/db.js">examples/content-negotiation/db.js</td>
|
|
334
|
-
<td>Douglas Christopher Wilson</td>
|
|
335
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
336
|
-
<td class="muted">—</td>
|
|
337
|
-
</tr>
|
|
338
|
-
<tr>
|
|
339
|
-
<td class="filepath" title="examples/content-negotiation/index.js">examples/content-negotiation/index.js</td>
|
|
340
|
-
<td>Douglas Christopher Wilson</td>
|
|
341
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
342
|
-
<td class="muted">—</td>
|
|
343
|
-
</tr>
|
|
344
|
-
<tr>
|
|
345
|
-
<td class="filepath" title="examples/content-negotiation/users.js">examples/content-negotiation/users.js</td>
|
|
346
|
-
<td>Douglas Christopher Wilson</td>
|
|
347
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
348
|
-
<td class="muted">—</td>
|
|
349
|
-
</tr>
|
|
350
|
-
<tr>
|
|
351
|
-
<td class="filepath" title="examples/hello-world/index.js">examples/hello-world/index.js</td>
|
|
352
|
-
<td>Douglas Christopher Wilson</td>
|
|
353
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
354
|
-
<td class="muted">—</td>
|
|
355
|
-
</tr>
|
|
356
|
-
<tr>
|
|
357
|
-
<td class="filepath" title="examples/mvc/controllers/main/index.js">examples/mvc/controllers/main/index.js</td>
|
|
358
|
-
<td>Douglas Christopher Wilson</td>
|
|
359
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
360
|
-
<td class="muted">—</td>
|
|
361
|
-
</tr>
|
|
362
|
-
<tr>
|
|
363
|
-
<td class="filepath" title="examples/mvc/controllers/pet/index.js">examples/mvc/controllers/pet/index.js</td>
|
|
364
|
-
<td>Douglas Christopher Wilson</td>
|
|
365
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
366
|
-
<td class="muted">—</td>
|
|
367
|
-
</tr>
|
|
368
|
-
<tr>
|
|
369
|
-
<td class="filepath" title="examples/mvc/controllers/user-pet/index.js">examples/mvc/controllers/user-pet/index.js</td>
|
|
370
|
-
<td>Douglas Christopher Wilson</td>
|
|
371
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
372
|
-
<td class="muted">—</td>
|
|
373
|
-
</tr>
|
|
374
|
-
<tr>
|
|
375
|
-
<td class="filepath" title="examples/mvc/db.js">examples/mvc/db.js</td>
|
|
376
|
-
<td>Douglas Christopher Wilson</td>
|
|
377
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
378
|
-
<td class="muted">—</td>
|
|
379
|
-
</tr>
|
|
380
|
-
<tr>
|
|
381
|
-
<td class="filepath" title="examples/route-separation/post.js">examples/route-separation/post.js</td>
|
|
382
|
-
<td>Douglas Christopher Wilson</td>
|
|
383
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
384
|
-
<td class="muted">—</td>
|
|
385
|
-
</tr>
|
|
386
|
-
<tr>
|
|
387
|
-
<td class="filepath" title="examples/route-separation/site.js">examples/route-separation/site.js</td>
|
|
388
|
-
<td>Douglas Christopher Wilson</td>
|
|
389
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
390
|
-
<td class="muted">—</td>
|
|
391
|
-
</tr>
|
|
392
|
-
<tr>
|
|
393
|
-
<td class="filepath" title="examples/session/redis.js">examples/session/redis.js</td>
|
|
394
|
-
<td>Douglas Christopher Wilson</td>
|
|
395
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
396
|
-
<td class="muted">—</td>
|
|
397
|
-
</tr>
|
|
398
|
-
<tr>
|
|
399
|
-
<td class="filepath" title="examples/vhost/index.js">examples/vhost/index.js</td>
|
|
400
|
-
<td>Douglas Christopher Wilson</td>
|
|
401
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
402
|
-
<td class="muted">—</td>
|
|
403
|
-
</tr>
|
|
404
|
-
<tr>
|
|
405
|
-
<td class="filepath" title="test/acceptance/hello-world.js">test/acceptance/hello-world.js</td>
|
|
406
|
-
<td>Douglas Christopher Wilson</td>
|
|
407
|
-
<td><span class="badge" style="background:#c084fc">100%</span></td>
|
|
408
|
-
<td class="muted">—</td>
|
|
409
|
-
</tr></tbody>
|
|
410
|
-
</table>
|
|
411
|
-
</section>
|
|
412
|
-
|
|
413
|
-
<section>
|
|
414
|
-
<h2>🔗 Implicit Coupling — files that always change together</h2>
|
|
415
|
-
<table>
|
|
416
|
-
<thead><tr><th>File A</th><th>File B</th><th>Co-changes</th><th>Coupling</th></tr></thead>
|
|
417
|
-
<tbody>
|
|
418
|
-
<tr>
|
|
419
|
-
<td class="filepath" title="benchmarks/Makefile">benchmarks/Makefile</td>
|
|
420
|
-
<td class="filepath" title="benchmarks/run">benchmarks/run</td>
|
|
421
|
-
<td>4</td>
|
|
422
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
423
|
-
</tr>
|
|
424
|
-
<tr>
|
|
425
|
-
<td class="filepath" title="test/regression.js">test/regression.js</td>
|
|
426
|
-
<td class="filepath" title="test/req.accepts.js">test/req.accepts.js</td>
|
|
427
|
-
<td>4</td>
|
|
428
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
429
|
-
</tr>
|
|
430
|
-
<tr>
|
|
431
|
-
<td class="filepath" title="test/regression.js">test/regression.js</td>
|
|
432
|
-
<td class="filepath" title="test/req.path.js">test/req.path.js</td>
|
|
433
|
-
<td>4</td>
|
|
434
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
435
|
-
</tr>
|
|
436
|
-
<tr>
|
|
437
|
-
<td class="filepath" title="test/req.accepts.js">test/req.accepts.js</td>
|
|
438
|
-
<td class="filepath" title="test/req.path.js">test/req.path.js</td>
|
|
439
|
-
<td>4</td>
|
|
440
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
441
|
-
</tr>
|
|
442
|
-
<tr>
|
|
443
|
-
<td class="filepath" title="examples/content-negotiation/db.js">examples/content-negotiation/db.js</td>
|
|
444
|
-
<td class="filepath" title="examples/mvc/controllers/main/index.js">examples/mvc/controllers/main/index.js</td>
|
|
445
|
-
<td>4</td>
|
|
446
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
447
|
-
</tr>
|
|
448
|
-
<tr>
|
|
449
|
-
<td class="filepath" title="examples/content-negotiation/db.js">examples/content-negotiation/db.js</td>
|
|
450
|
-
<td class="filepath" title="examples/mvc/db.js">examples/mvc/db.js</td>
|
|
451
|
-
<td>4</td>
|
|
452
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
453
|
-
</tr>
|
|
454
|
-
<tr>
|
|
455
|
-
<td class="filepath" title="examples/content-negotiation/db.js">examples/content-negotiation/db.js</td>
|
|
456
|
-
<td class="filepath" title="examples/route-separation/site.js">examples/route-separation/site.js</td>
|
|
457
|
-
<td>4</td>
|
|
458
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
459
|
-
</tr>
|
|
460
|
-
<tr>
|
|
461
|
-
<td class="filepath" title="examples/content-negotiation/users.js">examples/content-negotiation/users.js</td>
|
|
462
|
-
<td class="filepath" title="examples/route-separation/post.js">examples/route-separation/post.js</td>
|
|
463
|
-
<td>3</td>
|
|
464
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
465
|
-
</tr>
|
|
466
|
-
<tr>
|
|
467
|
-
<td class="filepath" title="examples/mvc/controllers/main/index.js">examples/mvc/controllers/main/index.js</td>
|
|
468
|
-
<td class="filepath" title="examples/mvc/db.js">examples/mvc/db.js</td>
|
|
469
|
-
<td>4</td>
|
|
470
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
471
|
-
</tr>
|
|
472
|
-
<tr>
|
|
473
|
-
<td class="filepath" title="examples/mvc/controllers/main/index.js">examples/mvc/controllers/main/index.js</td>
|
|
474
|
-
<td class="filepath" title="examples/route-separation/site.js">examples/route-separation/site.js</td>
|
|
475
|
-
<td>4</td>
|
|
476
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
477
|
-
</tr>
|
|
478
|
-
<tr>
|
|
479
|
-
<td class="filepath" title="examples/mvc/db.js">examples/mvc/db.js</td>
|
|
480
|
-
<td class="filepath" title="examples/route-separation/site.js">examples/route-separation/site.js</td>
|
|
481
|
-
<td>4</td>
|
|
482
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
483
|
-
</tr>
|
|
484
|
-
<tr>
|
|
485
|
-
<td class="filepath" title="examples/route-separation/views/index.jade">examples/route-separation/views/index.jade</td>
|
|
486
|
-
<td class="filepath" title="examples/route-separation/views/layout.jade">examples/route-separation/views/layout.jade</td>
|
|
487
|
-
<td>3</td>
|
|
488
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
489
|
-
</tr>
|
|
490
|
-
<tr>
|
|
491
|
-
<td class="filepath" title="examples/route-separation/views/index.jade">examples/route-separation/views/index.jade</td>
|
|
492
|
-
<td class="filepath" title="examples/route-separation/views/posts/index.jade">examples/route-separation/views/posts/index.jade</td>
|
|
493
|
-
<td>3</td>
|
|
494
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
495
|
-
</tr>
|
|
496
|
-
<tr>
|
|
497
|
-
<td class="filepath" title="examples/route-separation/views/index.jade">examples/route-separation/views/index.jade</td>
|
|
498
|
-
<td class="filepath" title="examples/route-separation/views/users/index.jade">examples/route-separation/views/users/index.jade</td>
|
|
499
|
-
<td>3</td>
|
|
500
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
501
|
-
</tr>
|
|
502
|
-
<tr>
|
|
503
|
-
<td class="filepath" title="examples/route-separation/views/index.jade">examples/route-separation/views/index.jade</td>
|
|
504
|
-
<td class="filepath" title="examples/route-separation/views/users/view.jade">examples/route-separation/views/users/view.jade</td>
|
|
505
|
-
<td>3</td>
|
|
506
|
-
<td><span class="badge" style="background:#f87171">100%</span></td>
|
|
507
|
-
</tr></tbody>
|
|
508
|
-
</table>
|
|
509
|
-
</section>
|
|
510
|
-
</main>
|
|
511
|
-
<footer>Generated by ⛏ Git Archaeologist</footer>
|
|
512
|
-
</body>
|
|
513
|
-
</html>
|