- 开发工具
- CLI
【免费下载链接】git-stats
🍀 Local git statistics including GitHub-like contributions calendars.
git-stats是一个面向本地的 Git 统计库:它把你在各仓库的提交记录聚合到本地数据文件中,并提供 GitHub 风格(contributions calendar)的 ANSI 贡献日历、作者分析饼图、增删行数统计与全局活动日历等能力。本文以 DOCUMENTATION.md 的 API 参考为骨架,逐方法讲解GitStats类全部接口的参数约定、返回值与源码实现细节,并给出可直接运行的库调用示例——读完你就能在自己的 Node.js 脚本或 CLI 工具中接入 git-stats,实现"私有化的贡献日历"。
类概览与数据模型
git-stats以 CommonJS 导出GitStats类(lib/index.js 中module.exports = GitStats)。从 2.x 起它是构造函数而非普通函数,因此你可以同时创建多个实例,各自指向不同的数据文件(详见 MIGRATION.md):
const GitStats = require("git-stats"); // 使用自定义数据路径 const gs1 = new GitStats("path/to/some/data.json"); // 使用默认路径(~/.git-stats) const gs2 = new GitStats();实例的全部方法采用Node.js 风格回调callback(err, data),多数方法在调用后返回实例自身,便于链式调用。
数据文件格式
所有统计都持久化在一个 JSON 文件中(默认~/.git-stats,由 lib/index.js 中的常量定义:DATE_FORMAT = "MMM D, YYYY"、DEFAULT_STORE = Abs("~/.git-stats")、DEFAULT_DATA = { commits: {} }、CONFIG_PATH = Abs("~/.git-stats-config.js"))。2.x 的数据结构为:
{ "commits": { "<date>": { "<hash>": 1 } } }其中<date>使用"MMM D, YYYY"格式(如"Jan 1, 2025")。对比 1.x 时代{ "<date>": { "<remote-url>": { "<hash>": "<date>" } } }的旧格式,新版本不再强制要求远端 URL,结构也更扁平;安装 2.x 时 scripts/migration/2.0.0.js 会自动迁移旧数据,失败时也可手动运行该脚本修复(参见 MIGRATION.md)。
构造实例:new GitStats(dataPath)
GitStats(dataPath)| 参数 | 类型 | 说明 |
|---|---|---|
dataPath | String | 数据文件路径(可选) |
返回值:GitStats实例。
从源码看(lib/index.js),构造器会把路径规范化为绝对路径并初始化配置字段:
constructor(dataPath) { this.path = Abs(Deffy(dataPath, DEFAULT_STORE)); // 未传则用 ~/.git-stats this.config = {}; }省略参数时默认使用~/.git-stats;传入路径时建议使用.json结尾的独立文件,便于多项目隔离统计。
配置系统:getConfig与initConfig
git-stats 支持通过用户主目录下的~/.git-stats-config.js配置文件(CommonJS 模块)统一调整默认行为,这与 README 中"Using the configuration file"一节保持一致。
getConfig(callback)
从~/.git-stats-config.js读取配置对象。
| 参数 | 类型 | 说明 |
|---|---|---|
callback | Function | 回调函数 |
返回值:Object | Undefined——不传回调时直接返回配置对象;传回调时以callback(err, data)形式返回。
实现要点(lib/index.js):使用require(CONFIG_PATH)加载配置;若文件不存在(MODULE_NOT_FOUND)则视作空配置{}而非报错。这意味着配置文件缺失不会中断程序,只会退回到内置默认值。
initConfig(input, callback)
初始化实例的this.config字段。
| 参数 | 类型 | 说明 |
|---|---|---|
input | Object | String | 自定义配置文件的路径,或直接传入配置对象(可选) |
callback | Function | 回调函数 |
实现要点(lib/index.js):
- 若第一个参数是函数,则视其为
callback并回落到默认配置路径; - 若传入对象,则与
GitStats.DEFAULT_CONFIG做深合并(Ul.deepMerge),立即生效; - 若传入字符串路径或省略,则先
getConfig读取,再递归进入对象合并分支。
内置默认配置定义在 lib/index.js 的GitStats.DEFAULT_CONFIG:
GitStats.DEFAULT_CONFIG = { theme: "DARK", // 默认深色主题;可取值 "DARK"、"LIGHT" 或颜色对象 path: undefined, // 数据文件路径,缺省在库内部取 ~/.git-stats first_day: undefined, // [已废弃] 一周起始日,默认交给 cli-gh-cal 处理 since: undefined, // 统计起始日期,默认一年前 until: undefined, // 统计结束日期,默认现在 authors: false, // 默认不显示作者饼图 global_activity: false // 默认不显示全局活动日历 };对应的配置文件(~/.git-stats-config.js)完整默认值示例:
module.exports = { // "DARK"、"LIGHT" 或一个可由 node-git-stats-colors 解释的对象 "theme": "DARK" // 提交哈希的存储文件 , "path": "~/.git-stats" // [已废弃] 一周的第一天 https://github.com/IonicaBizau/git-stats/issues/121 , first_day: "Sun" // 默认是"一年前";可以是任意可解析的日期 , since: undefined // 默认是"现在";可以是任意可解析的日期 , until: undefined // 默认不显示作者;设为 true 将启用作者饼图 , authors: false // 默认不显示全局活动;设为 true 将启用当前项目的全局活动日历 , global_activity: false };因为它是 JS 文件,你可以在其中require任意模块来动态生成配置。
提交记录管理:record与removeCommit
这两个方法分别用于写入与删除一条提交记录,是"私有贡献日历"的数据入口——git 的 post-commit hook 正是通过--record调用record完成自动统计的(见 scripts/init-git-post-commit 生成的 hook 内容)。
record(data, callback)
记录一条新提交。
| 参数 | 类型 | 说明 |
|---|---|---|
data.date | String | Date | 日期对象,或可解析的日期字符串 |
data.url | String | 仓库远端 URL(可选) |
data.hash | String | 提交哈希 |
data._data | Object | 若提供,应为 git-stats 数据文件内容的对象;会在内存中修改后返回,不重新读盘 |
data.save | Boolean | 若为false,结果不会写入文件 |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):
- 校验:
date必须是字符串或 Date 对象,否则回调错误"The date field should be a string or a date object.";hash必须是非空字符串,否则回调"Invalid hash."; - 存储:日期统一格式化为
DATE_FORMAT("MMM D, YYYY"),当天提交对象以day[hash] = 1的方式去重记录,因此同一哈希重复写入不会重复计数; - 落盘控制:
data.save === false时只返回内存中的统计对象;否则调用save写回文件; - 内存模式:传入
_data可避免再次读盘,直接在传入对象上修改(注意:未传save: false时仍会保存)。
removeCommit(data, callback)
删除历史中的某条提交记录(原文档中该条目标题写作record,实际导出的方法名为removeCommit)。
| 参数 | 类型 | 说明 |
|---|---|---|
data.date | String | Date | 日期对象或可解析字符串(可选;不提供时按哈希在所有日期中查找) |
data.hash | String | 提交哈希 |
data._data | Object | 若提供,为数据文件内容对象,在内存中修改后返回 |
data.save | Boolean | 若为false,结果不会写入文件 |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):与record的差异在于——日期非法或缺失时置为null,随后遍历所有日期删除匹配的哈希(IterateObject(stats.commits, ...));提供日期则只删除该日期的条目。其余校验、_data内存模式与save控制逻辑与record一致。
数据读写:get与save
get(callback)
获取全部 git 统计数据。
| 参数 | 类型 | 说明 |
|---|---|---|
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):读取this.path指向的 JSON 文件;若文件不存在(ENOENT),会先写入DEFAULT_DATA({ commits: {} })再回调该默认值——首次使用时无需手动初始化。
save(stats, callback)
保存给定的统计数据。
| 参数 | 类型 | 说明 |
|---|---|---|
stats | Object | 要保存的统计对象(形如{ commits: { "<date>": { "<hash>": 1 } } }) |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):底层使用w-json的WriteJson原子写入,record、removeCommit的落盘最终都会走到这里。
时间遍历与统计:iterateDays、graph、calendar、ansiCalendar
iterateDays(data, callback)
按天遍历日期区间,对每一天调用回调。
| 参数 | 类型 | 说明 |
|---|---|---|
data.start | Moment | 起始日期(默认:一年前) |
data.end | Moment | 结束日期(默认:现在) |
data.format | String | 日期格式化字符串(默认:"MMM D, YYYY") |
callback | Function | 回调,接收当前日期的格式化字符串(string)与对应的 Moment 对象 |
返回值:GitStats实例。
实现细节(lib/index.js):将 start/end 规范化为DATE_FORMAT粒度的 Moment 后,从 start 逐日递增到 end(含 end),回调参数为(格式化日期, Moment对象);data可省略(或直接传函数作为首个参数),此时使用默认区间。
graph(data, callback)
生成指定时间段(默认:最近一年)内每一天的统计对象。
| 参数 | 类型 | 说明 |
|---|---|---|
data | Object | 传给iterateDays的参数对象 |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):内部先get读取全部数据,再借iterateDays逐日组装,结果形如:
{ "Jan 1, 2025": { "_": { "<hash>": 1 }, "c": 1 }, "Jan 2, 2025": { "_": {}, "c": 0 } // ... }即每天包含_(当日哈希集合)与c(当日提交数)。
calendar(data, callback)
基于graph的结果生成汇总日历数据(默认:最近一年)。
| 参数 | 类型 | 说明 |
|---|---|---|
data | Object | 传给graph方法的参数对象 |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):返回对象包含total(总提交数)、days(每日明细)、cStreak(当前连续贡献天数)、lStreak(最长连续贡献天数)、max(单日最大提交数)、activeDays(有提交的天数)。每日明细days[date] = { c, level }中,level为 0~4 的贡献等级,其计算基于常量LEVELS = [0, 1, 2, 3, 4]:
- 档位步长
levels = cal.max / (LEVELS.length * 2); level = Math.round(c / levels),上限封顶为4;- 若计算值为
0但当天确有提交(c > 0),强制取1,保证活跃天至少有低等级标记。
ansiCalendar(options, callback)
生成 ANSI 贡献日历(终端直接渲染的 GitHub 风格日历)。
| 参数 | 类型 | 说明 |
|---|---|---|
options | Object | 传给calendar方法的参数对象(可含theme、start、end、raw、firstDay等) |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):先调用calendar拿到含activeDays的汇总数据,再iterateDays组装[日期, 提交数]对,最终交给cli-gh-cal渲染 ANSI 日历字符串;options.raw为真时返回对象形式数据。库用法示例见下文 example/index.js 一节。
作者分析:authors、authorsPie、authorsStats、authorsStatsPie
这组方法直接从指定 git 仓库(而非本地统计数据文件)读取提交历史,用于作者维度分析。
authors(options, callback)
返回某 git 仓库的作者列表(含各自提交数)。
| 参数 | 类型 | 说明 |
|---|---|---|
options | String | Object | 仓库路径,或包含以下字段的对象 |
options.repo | String | 仓库路径 |
options.start | String | 起始日期 |
options.end | String | 结束日期 |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):通过gry在仓库中执行git shortlog -s -n --all --since <start> --until <end>,解析输出为[{ value, label }],其中value为该作者的提交数(整数),label为作者名。
authorsPie(options, callback)
生成作者贡献饼图。
| 参数 | 类型 | 说明 |
|---|---|---|
options | String | Object | 仓库路径,或包含以下字段的对象 |
options.repo | String | 仓库路径 |
options.radius | Number | 饼图半径 |
options.no_ansi | Boolean | 若为true,饼图不含 ANSI 字符 |
options.raw | Boolean | 若为true,输出原始 JSON |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):传入字符串时自动包装为{ repo };半径默认取process.stdout.rows / 2 || 20;仓库目录不存在时回调"The repository folder doesn't exist.";作者数量超过2 * radius时,超出部分合并为"Others"一项;raw为真返回含legend、flat、no_ansi、authors的数据对象,否则返回cli-pie渲染的字符串。
authorsStats(options, callback)
返回作者及其增删行数统计数组。
| 参数 | 类型 | 说明 |
|---|---|---|
options | String | Object | 仓库路径,或包含以下字段的对象 |
options.repo | String | 仓库路径 |
options.start | String | 起始日期 |
options.end | String | 结束日期 |
options.mode | String | 'additions'、'deletions'或'both'(默认:'both') |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):默认时间区间同样为一年前至今;底层执行git log --pretty=format:%aN --numstat --since <start> --until <end>并逐行解析--numstat的新增\t删除\t文件名三元组累加到对应作者。结果按mode组织:additions时value为新增行数且标签为作者 (+N),deletions时为删除行数(作者 (-N)),both时为增删之和(作者 (+N/-M));每项同时保留author、additions、deletions原始字段;过滤value <= 0的项并按value降序排列。
authorsStatsPie(options, callback)
基于authorsStats的结果绘制作者增删统计饼图。
| 参数 | 类型 | 说明 |
|---|---|---|
options | String | Object | 仓库路径,或包含以下字段的对象 |
options.repo | String | 仓库路径 |
options.start | String | 起始日期 |
options.end | String | 结束日期 |
options.mode | String | 'additions'、'deletions'或'both'(默认:'both') |
options.radius | Number | 饼图半径 |
options.no_ansi | Boolean | 若为true,饼图不含 ANSI 字符 |
options.raw | Boolean | 若为true,输出原始 JSON |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):默认半径同上,mode默认'both';先调用authorsStats,再套用与authorsPie相同的"超出2 * radius合并为 Others、raw控制输出形式"逻辑。
全局活动日历:globalActivity(options, callback)
生成全局贡献日历——统计指定仓库中所有提交者(而非仅限本地统计文件)产生的全部提交。
| 参数 | 类型 | 说明 |
|---|---|---|
options | String | Object | 仓库路径,或包含以下字段的对象 |
options.repo | String | 仓库路径 |
options.start | String | 起始日期 |
options.end | String | 结束日期 |
options.theme | String | Object | 日历主题 |
options.raw | Boolean | 若为true,输出原始 JSON |
callback | Function | 回调函数 |
返回值:GitStats实例。
实现细节(lib/index.js):仓库目录不存在时回调"The repository folder doesn't exist.";通过git log --since <start> --until <end>(起始/结束需为可format的日期对象)生成提交流,用gitlog-parser逐条解析并统计每天的提交数,最后交给cli-gh-cal渲染日历。此外,从源码实现看(lib/index.js),options还支持可选的author字段,用于把全局日历过滤到指定作者。
完整库用法示例
仓库 example/index.js 展示了最简单的日历渲染用法:
// Dependencies const GitStats = require("../lib"); // Create the GitStats instance const g1 = new GitStats(); // Display the ansi calendar g1.ansiCalendar({ theme: "DARK" }, function (err, data) { console.log(err || data); });example/author-stats.js 展示了作者增删统计的完整调用链(both/additions/deletions三种模式与raw输出):
// Dependencies const GitStats = require("../lib"); // Create the GitStats instance const g1 = new GitStats(); // Display author statistics (both additions and deletions) g1.authorsStatsPie({ repo: process.cwd(), mode: "both" }, function (err, data) { console.log(err || data); // Display only additions g1.authorsStatsPie({ repo: process.cwd(), mode: "additions" }, function (err, data) { console.log(err || data); // Display only deletions g1.authorsStatsPie({ repo: process.cwd(), mode: "deletions" }, function (err, data) { console.log(err || data); // Display raw JSON data g1.authorsStats({ repo: process.cwd(), mode: "both" }, function (err, data) { console.log(err || JSON.stringify(data, null, 2)); }); }); }); });作为库安装(本地依赖)时:npm install git-stats(或yarn add git-stats)。
底层实现与 CLI 的映射关系
CLI 入口 bin/git-stats 把命令行选项逐一映射到上述 API(require("..")即加载 lib/index.js):
| CLI 选项 | 映射的 API | 说明 |
|---|---|---|
--record <data> | record(options, cb) | 记录一条新提交(JSON 解析后写入),hook 脚本 scripts/init-git-post-commit 通过它自动统计每次 commit |
-a, --authors | authorsPie | 显示当前仓库作者贡献饼图(repo取process.cwd()) |
-S, --author-stats | authorsStatsPie | 配合-M, --stats-mode <additions\|deletions\|both>指定统计口径(默认both) |
-A, --author <name> | globalActivity的author过滤 | 过滤指定作者的贡献 |
-g, --global-activity | globalActivity | 显示当前仓库全局活动日历 |
-s, --since/-u, --until | options.start/options.end | 可解析日期字符串,缺省为一年前/现在 |
-r, --raw | 各方法的raw选项 | 输出原始 JSON |
-l, --light | theme: "LIGHT" | 浅色主题 |
-n, --disable-ansi | theme: null | 禁用 ANSI 样式 |
-d, --data <path> | this.path | 自定义数据存储文件(需已存在) |
CLI 读取~/.git-stats-config.js的方式正是initConfig();配置中的path、authors、global_activity会分别自动触发--data、-a、-g行为(bin/git-stats)。配置中的theme字符串只在DARK/LIGHT时生效,其余情况回落为 CLI 参数决定(bin/git-stats)。
结合 CLI 的生态与进阶用法
- 自动记录每次提交:全局安装 git-stats 后,通过 scripts/init-git-post-commit 初始化 git 全局模板目录的
post-commithook,每次git commit后自动调用git-stats --record,把git rev-parse HEAD、remote.origin.url与%cI提交时间写入本地数据文件; - 导出 HTML 与图片:
git-stats --raw输出原始 JSON,可交给社区工具(如 git-stats-html)渲染为 HTML,再用 pageres 等工具把 HTML 转成图片——即"日历转图片"的经典链路; - 跨平台注意:日历与饼图依赖 ANSI 样式,在 Linux 与 macOS 的终端模拟器上表现良好;Windows 上需要支持 ANSI 颜色的终端(如 Cygwin Terminal),Windows Command Prompt 与 Git Bash 无法正确显示图形(详见 README.md 的 Cross-platform compatibility 一节)。
小结
GitStats类的方法可以划分为四组能力:配置与数据读写(getConfig、initConfig、get、save)、提交记录增删(record、removeCommit)、个人统计与日历渲染(iterateDays、graph、calendar、ansiCalendar)、仓库作者分析(authors、authorsPie、authorsStats、authorsStatsPie、globalActivity)。无论是要在 CI 脚本中输出贡献报告、把统计嵌入自己的工具链,还是复刻一个"本地版 GitHub 贡献日历",都可以直接从 DOCUMENTATION.md 的这份 API 契约出发,配合 lib/index.js 的实现细节按需调用。
- 开发工具
- CLI
【免费下载链接】git-stats
🍀 Local git statistics including GitHub-like contributions calendars.
相关推荐
Git-Stats终极指南:如何在本地生成GitHub风格贡献日历
想要在自己的终端中查看GitHub风格的贡献日历吗?😊 git stats工具让你能够在本地生成精美的Git提交统计图表,无需联网即可查看所有git提交记录。
开发工具CLI大麦网自动抢票终极指南:告别手速焦虑,轻松搞定热门演出门票
大麦网自动抢票终极指南:告别手速焦虑,轻松搞定热门演出门票 还在为抢不到心仪演唱会门票而烦恼吗?每次热门演出开票,你是不是也经历过这样的场景:盯着屏幕刷新到手抽
网页爬虫工作流自动化NextExplorer高级部署:反向代理配置与HTTPS安全加固
NextExplorer高级部署:反向代理配置与HTTPS安全加固 NextExplorer作为一款Web based File Explorer,提供了便捷的
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考