Catalog npm
Back to packageRELEASE DETAILS

2.2.8

npm

@076lik/git-panel

轻量级局域网 Git 仓库与 CI/CD 管理平台

cdcigitlanrepositoryself-hostedwebhook
Published8 Jun 2026
Direct dependencies3
Transitive dependenciesNot calculated

README

Current package documentation

Git Panel

本地 Git 仓库与 CI 流水线管理平台,提供类 GitHub 的 Web 界面。

它不是 Demo,而是已在生产环境长期运行的完整平台:本机(龙芯 loongarch64 / AOSC OS)上托管着 9 个真实仓库,年复一年地承担推送、构建、部署与外部同步。文中列出的每一项能力都在真实仓库上验证过,包括那些"只在出问题时才用得到"的部分(快照回滚、孤儿构建校正、失效地址清理)。

零认证、零数据库、纯文件系统存储:插上硬盘、跑一条命令就能用。

仪表盘

更多界面见下方界面预览。

功能特性

仓库与协议

  • 三重协议并行:Git Smart HTTP(可推可拉)、SSH、git:// daemon,局域网内免认证开放
  • 任意存储路径:仓库根可放在外部硬盘/USB,Web 界面一键修改;路径解析在后端、部署脚本、CI 三处统一
  • Git LFS 服务端:完整的 Batch API(上传/下载协商),支持一键启用与关闭(关闭时保留对象,不破坏历史提交)
  • 分支与标签管理:创建、删除、切换;分支切换状态不会被刷新重置
  • 文件浏览:目录树、README 渲染、原始字节下载、归档打包下载
  • 多格式预览:JSON 树、CSV 表格、Diff/Patch 着色、Log 级别高亮、PDF/图片/视频/音频、Markdown
  • 文件树实时搜索、全库代码搜索
  • 分支对比:任选两个分支/标签,查看文件级差异(状态、增删统计、按需展开单文件 patch)
  • 提交 diff 查看器:点击提交查看该次改动的文件列表与逐文件差异
  • 语言统计:基于 cloc,自动排除文档/配置/脚本

存储与快照

  • 三级快照降级链:btrfs 原生只读子卷快照(零额外空间、秒级)→ reflink 复制(XFS 等)→ 普通复制(ext4 等)
  • 不支持的磁盘自动退回普通复制,并在界面上明确提示会占用额外空间,绝不静默失败
  • 子卷转换:把已有仓库原地转为 btrfs 子卷以启用原生快照,失败自动回滚(fsck 校验、旧数据不丢)
  • 快照恢复:btrfs 用原子换名,保留原快照;支持快照列表、删除与保留策略

CI/CD

  • 推送自动触发构建:post-receive 钩子从 stdin 解析真实分支并自动校正悬空 HEAD
  • CI 配置自动识别:GitHub Actions / GitLab CI 兼容,另有 Python·UV / C·C++ / Go / Rust / Java / TypeScript / Lua 多语言模板
  • CD 持续部署:构建成功后执行部署步骤,也支持手动触发
  • 构建看板与统计:历史趋势、成功/失败占比、日历热力图
  • 构建日志:按步骤折叠、ANSI 颜色渲染、按日期分组
  • 孤儿状态自愈:服务重启后自动校正"卡在构建中"的残留状态(三重存活校验,防 PID 复用误判)
  • 构建产物清理:按保留策略清理旧 Release,支持预览,开发版始终保留
  • 外部智能体接口:GET /build-summary 供轮询最新状态;/api/help 自描述全部 99 个端点

通知与集成

  • Webhook 统一管理页:按地址而不是按仓库汇总,一眼看到每个地址被哪些仓库使用、投递成功率、最后投递时间,可一次性从所有引用处移除
  • 历史残留地址识别:自动找出"已不在任何配置里、却仍在刷失败记录"的地址(换 IP / 服务下线后的残留),支持逐个或批量清理
  • 通知中心:全局聚合投递记录、未读角标、按事件类型静音、桌面系统通知(KDE 等 Linux 桌面实测可用)
  • 记录清理:按天数 / 只清失败 / 清空全部,支持按仓库或按地址限定;先预览条数再执行
  • 远程同步:一键推送到 Gitee / GitCode / GitHub 等外部远端

权限与运维

  • SSH 公钥管理:支持 curl 一键提交(/api/ssh-keys/raw)
  • 部署令牌管理:面向 CI/脚本的访问令牌
  • 用户显示名与颜色:按客户端 IP 记录,活动日志中可区分是谁
  • 活动日志(审计):全量操作留痕,按日期折叠,可跳转仓库
  • 磁盘监控、存储能力探测
  • 系统配置:仓库路径、数据路径、全局 Webhook 集中配置
  • 一键重启服务(需配置 NOPASSWD sudoers 规则)

工程与质量

  • 17 个测试套件、236 个用例:覆盖钩子生成、版本解析、快照降级链、diff 解析、通知水位线、孤儿判定、清理边界等易错路径
    • 其中 webhook-api.test.ts 会真起服务进程 + 真发 HTTP(隔离临时目录),因为有些缺陷只有跑起来才暴露
  • 后端核心逻辑抽成无副作用模块,可被测试直接引入
  • 99 个 API 端点全部登记进 /api/help,并有测试守护防止漏登
  • Vue 3 SPA 前端,GitHub Dark Dimmed 主题,响应式布局
  • Nginx 反向代理(关闭缓冲以支持大仓库推送),配置由模板生成、模板本身保持可移植
  • systemd 托管:KillMode=process 保证重启面板不会连带杀掉正在跑的构建

这工具适合谁?

✅ 适合❌ 不适合
3-5 人小团队,不想买 GitHub Pro / GitLab 企业版你需要多租户、RBAC 权限管理(请用 GitLab)
你在局域网/内网开发,没有公网 IP 和域名你需要 GitHub Actions 的云端并行构建矩阵
你的构建产物很大,想存到外部硬盘/USB你需要 Kubernetes + Docker 的容器化 CI
你想推送代码后自动构建、自动发版,但不想写 YAML你需要复杂的流水线编排(如 Jenkins Pipeline)
你的服务器是龙芯/ARM 等特殊架构,主流 CI 不支持你需要 SaaS 托管(如 GitHub Actions、Travis CI)
你想秒级备份仓库(btrfs 原生快照 / reflink),硬盘坏了不怕你已经有完善的 DevOps 基础设施
你想让外部智能体/设备通过 Webhook 与构建状态接口接入你的仓库必须放到公网(本项目为可信局域网设计,无鉴权)

一句话:当你想在自己的局域网里搭一个"够用"的 GitHub,零认证、零数据库、插上硬盘就能跑的时候。

⚠️ 安全边界:面板默认无鉴权,仅供可信局域网使用,不要直接暴露到公网。若需公网访问,请自行在反向代理层加认证与 TLS。


界面预览

以下截图取自真实运行环境(龙芯 loongarch64,浏览器全屏访问 http://192.168.1.64),其中托管着 9 个真实仓库。

落地页 —— 打开面板先看到连接方式与上手说明:三种协议怎么用、怎么建仓库、CI/CD 怎么接

落地页

仪表盘 —— 存储路径、磁盘余量、仓库列表与最近活动一屏可见

仪表盘

仓库详情 —— 文件树、README 渲染、分支切换、提交历史;右侧是当前提交的说明

仓库详情

CI/CD 构建历史 —— 按日期分组折叠、今天默认展开;上方是当前构建的步骤与实时状态

CI/CD 构建历史

Webhook 统一管理 —— 按地址而不是按仓库汇总:谁在用、成功率、最后投递时间,失效地址可从所有引用处一次移除

Webhook 统一管理

通知中心 —— 全局聚合投递记录,支持按事件类型静音、桌面系统通知与按条件清理(先预览条数再执行)

通知中心


项目结构

git-panel/
├── client/          # Vue 3 + TypeScript 前端
│   └── src/
│       ├── components/    # 页面与通用组件(仓库、快照、令牌、Webhook 管理…)
│       ├── extensions/    # 扩展页(构建统计、磁盘监控、代码搜索、通知中心)
│       ├── App.vue
│       └── main.ts
├── server/          # Express + TypeScript 后端
│   ├── server.ts          # 主入口(99 个 API 端点)
│   ├── ci-runner.py       # CI 编排器(构建、部署、Webhook 投递)
│   ├── hooks-template.ts  # post-receive 钩子的唯一权威实现
│   ├── storage-fs.ts      # 快照三级降级链与子卷转换
│   ├── diff-engine.ts     # 分支/提交 diff
│   ├── webhook-cleanup.ts # 投递记录清理的判定逻辑
│   ├── git-process-reaper.ts # 收割重启遗留的孤儿 git-http-backend
│   ├── deploy-config.ts   # 仓库根解析(后端/部署脚本/CI 共用)
│   ├── version.ts         # 版本号解析
│   ├── tests/             # 17 个套件、236 个用例
│   └── extensions/        # 扩展路由(构建统计、磁盘、代码搜索)
├── scripts/         # 特权助手(btrfs)与安装脚本
├── web-dist/        # 前端构建产物
├── nginx-full.conf  # Nginx 配置模板(含占位符)
├── deploy.sh        # 一键部署脚本
└── 版本记录.html     # 完整变更历史(含每项的动机与验证方式)

快速开始

方式一:npm 全局安装(推荐)

npm install -g @076lik/git-panel

# 启动服务(普通用户)
git-panel

# 自定义端口或仓库路径
git-panel --port=8080 --repo-root=/data/git

系统部署(一次性,需要 sudo):

sudo git-panel-deploy

git-panel-deploy 会自动完成:环境预检 → 安装依赖 → 编译前后端 → 生成 nginx 配置 → 创建 systemd 服务 → 配置防火墙 → 启动服务。

方式二:源码一键部署

cd /home/lik/git-panel
sudo bash deploy.sh

deploy.sh 会自动完成:环境预检 → 安装依赖 → 编译前后端 → 生成 nginx 配置 → 创建 systemd 服务 → 配置防火墙 → 启动服务。

环境变量覆盖(可选):

sudo USER=lik REPO_DIR=/home/lik/git PORT=3456 bash deploy.sh

方式三:手动开发模式

如需本地开发调试:

# 后端(ts-node 热重载)
cd server && npm install && npm run dev

# 前端(Vite 热重载)
cd client && npm install && npm run dev

仓库存储路径

默认存储在 ~/git,支持通过前端「系统配置」面板修改,保存后点击「重启服务」即可生效(无需手动操作命令行)。

Nginx 与防火墙

deploy.sh 已自动配置。如需手动:

# Nginx
sudo nginx -c /home/lik/git-panel/nginx-full.conf

# 防火墙(firewalld 示例)
sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --add-port=9418/tcp --permanent
sudo firewall-cmd --reload

防火墙配置(如需手动)

某些发行版(如 AOSC OS)默认会拒绝 1-1024 端口的入站连接。

图形化方式(AOSC OS):

打开 系统设置 → WiFi 和互联网 → 网络设置 → 防火墙设置 → 在列表中 勾选 http → 点击 确定 → 点击 应用。

命令行方式(firewalld):

# 仅允许局域网(推荐)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.3.0/24" service name="http" accept'
sudo firewall-cmd --reload

# 全局开放(不推荐暴露在公网)
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload

连接方式

协议地址说明
Web 面板http://192.168.3.130/Nginx 反向代理,标准 80 端口
Git (只读)git://192.168.3.130/repo.gitgit daemon,端口 9418
HTTP (推送)http://192.168.3.130/api/git/repo.gitNginx → Node.js 3456
SSHlik@192.168.3.130:/run/media/lik/git/repo.git标准 22 端口

技术栈

  • 后端: Node.js 20, Express, TypeScript, git-http-backend CGI 代理
  • 前端: Vue 3, TypeScript, Vite, highlight.js, marked
  • 基础设施: Nginx, btrfs/XFS(快照后端自动探测), Git LFS
  • 测试: Node 内置断言 + 真实 git 仓库集成测试(无第三方测试框架依赖)
  • 工具链: cloc(语言统计)

语言统计过滤规则

语言统计基于 cloc 计算代码行数,自动排除以下非代码类别:

类型被排除的语言
文档Markdown、reStructuredText、TeX、Text
配置/数据JSON、YAML、XML、TOML、INI、CSV
样式HTML、CSS、SCSS、Less、Sass
构建/脚本Dockerfile、Containerfile、Makefile、make、CMake、Gradle、Shell、Bash、PowerShell、Batch
其他Log、Source Map、SVG

如果排除后没有剩余语言,则自动回退显示全部结果(避免空列表)。

推送大仓库优化

git config --global pack.windowMemory 512m
git config --global pack.threads 4
git config --global http.postBuffer 2097152000

以上为可选的性能调优。需要说明一个曾经的真实缺陷及其修复,避免你再踩:

曾经:pack 体积超过 http.postBuffer(默认仅 1 MiB)时推送必然失败。 超过该阈值后 git 会改用 chunked 传输(无 Content-Length),而服务端代理把 环境变量写成了 CONTENT_LENGTH: req.headers['content-length'] || '0' —— git 的 receive-pack 在缺 Content-Length 时是直接报错退出的,'0' 等于告诉它「没有请求体」, 于是客户端看到:

send-pack: unexpected disconnect while reading sideband packet
致命错误:远端意外挂断了

已修复:仅在客户端真的给了 Content-Length 时才设置该变量,未给则交由 git http-backend 按「读到 stdin EOF」处理(这正是 chunked 所需)。 修复后 2.38 MB 的载荷在默认配置下推送成功,包体完整(fsck 干净、对象可读)。 回归测试 server/tests/git-http-push.test.ts 用 -c http.postBuffer=1 强制走 chunked 路径,已实测可复现该缺陷(还原缺陷代码即变红)。

这与仓库大小无关,只与单次推送的 pack 体积有关 —— 纯文本小提交在很大的仓库上 一直都能正常推送,这也解释了为什么它长期难以定位。

测试

后端核心逻辑已抽成无副作用模块,并有回归测试覆盖:

cd server && npm test        # 17 个套件,236 个用例
套件覆盖内容
post-receive-hook.test.ts钩子从 stdin 解析分支、HEAD 自动校正、删除/标签推送不触发构建
version.test.ts版本号解析(源码布局 / npm 安装布局 / 兜底)
deploy-config.test.ts仓库根解析优先级、尾斜杠归一化、配置损坏降级、CLI 输出洁净度
storage-backend.test.ts快照三级降级链的判定与命令分派、路径穿越防护、转换失败回滚
ci-liveness.test.tsCI 孤儿状态判定(三重存活校验、pid 复用防护)
diff-engine.test.tsref 注入防护、numstat/name-status 解析、改名与二进制边界
notif-read.test.ts通知未读水位线语义与边界
notif-prefs.test.ts按事件类型静音、桌面通知三重过滤、通知文案
info-page-icons.test.ts落地页内联图标与 client/src/icons/index.ts 一致性
api-help-coverage.test.ts所有 Express 路由都已登记进 /api/help
ci-runner-paths.test.ts后端 / deploy.sh / ci-runner.py 三方的路径优先级一致(且后两者复用同一实现)
webhook-cleanup.test.ts投递历史清理的判定边界(时间缺失一律保留、失败判定、按地址过滤与排除)
git-process-reaper.test.ts孤儿 git-http-backend 收割的保守判定(后代链、命令行、仓库根三重校验)
git-backend-env.test.tsCONTENT_LENGTH 构造规则(chunked 缺该头时绝不能设成 '0')+ 其余 CGI 变量
git-http-push.test.ts真起服务 + 真跑 git push:chunked(大 pack)推送、pack 完整性与 fsck
webhook-api.test.ts真起服务进程 + 真发 HTTP:统一管理聚合、残留地址识别、清理模式与确认守卫、scope="all" 覆盖全部仓库

测试由 npm test 自动发现 dist/tests/*.test.js —— 新增套件无需改脚本, 避免手工清单漏跑而静默失去保护(api-help-coverage 就曾被漏掉)。

测试不能继承调用方的 git 上下文(CI 的构建目录本身是裸仓库,会导出 GIT_DIR), 统一通过 server/tests/helpers.ts 的 gitEnv() 隔离。验证时可用 GIT_DIR=<裸仓库> npm test 复现 CI 条件。

作者声明

作者: H076lik

本项目由 H076lik 独立构思、设计并主导开发。所有功能均根据实际局域网 DevOps 需求设计,技术栈(Vue 3 + Express + btrfs/XFS 快照后端 + Python CI Runner)由作者自主决定。

开发过程中使用了 AI 智能体(如 Crush、Claude Code 等)作为代码生成与调试的辅助工具。AI 智能体仅作为开发工具使用,类似于 IDE、编译器等辅助软件,不构成共同创作。所有代码的架构决策、功能设计、逻辑审查、测试验证以及最终知识产权均归属于 H076lik。


赞助名单

如果您觉得本项目对您有帮助,欢迎赞助支持开发。 联系方式与赞助方式待补充...

赞助者金额 / 方式日期留言
待填写———

许可证

本项目采用 GNU Lesser General Public License v3.0 (LGPL-3.0) 开源许可。

  • 核心源码(client/src/、server/、配置文件及部署脚本)均已在文件头部添加 LGPL-3.0 标准声明
  • 允许商用、修改与再分发,但修改后的库文件需以相同许可证开源
  • larger work(调用本平台的应用程序)可独立使用不同许可证,无需强制开源
  • 完整许可证文本见仓库根目录 LICENSE 文件

法律说明:本项目为独立实现的 Git 仓库与 CI/CD 管理平台。功能接口与 DevOps 流程参考了开源社区(包括 GitHub、GitLab)的成熟实践,但全部代码由 H076lik 独立编写。

Copyright (C) 2025-2026 H076lik

CI/CD 完整指南

Git Panel 内置完整的持续集成/持续部署流水线,支持自动构建、部署和外部通知。

CI 流水线(自动构建)

推送代码后自动触发:

  1. 检出代码到 deploy/{repo}
  2. 执行配置的构建步骤(如 npm run build、cargo build、go test)
  3. 支持自动检测项目类型(Rust/Go/TypeScript/Python/C/C++/Java/Lua)
  4. 自动识别 .github/workflows/*.yml 和 .gitlab-ci.yml
  5. CI 配置工作流化:手动配置的构建步骤保存为 .github/workflows/git-panel-ci.yml 并自动 git commit,配置与代码一起版本控制
  6. 自动发布起始版本号:Dev Release 支持设置起始版本号(如 2.0.0),自动递增 v2.0.1 → v2.0.2

CD 持续部署

构建成功后自动执行部署步骤:

  • 在 CI 配置中勾选「构建成功后自动部署」
  • 添加部署命令(如 cp target/release/app /opt/bin/)
  • 支持手动触发 POST /api/repos/{name}/deploy

Webhook 通知

构建/部署完成后向局域网内其他设备/智能体发送 HTTP POST 通知:

# 配置 Webhook(前端 CI/CD → 配置 Webhook)
# 或使用 API
POST /api/repos/{name}/webhook
{
  "enabled": true,
  "url": "http://192.168.3.xxx:8080/webhook",
  "events": ["build.failed", "build.success", "deploy.failed", "deploy.success"]
}

推送内容示例:

{
  "event": "build.failed",
  "repo": "YouLiLong",
  "branch": "master",
  "commit": "c993fe94...",
  "commitMsg": "refactor(dap): ...",
  "runId": "1778663640",
  "status": "failed",
  "steps": [{"name": "Build release", "status": "failed"}],
  "timestamp": "2026-05-13T17:34:00",
  "server": "git-panel"
}

构建摘要 API(外部智能体查询)

GET /api/repos/{name}/build-summary

返回示例:

{
  "repo": "YouLiLong",
  "ci": {
    "status": "success",
    "runId": "1778665915",
    "branch": "master",
    "commit": "13aa0970...",
    "duration": 8,
    "steps": [{"name": "Build Client", "status": "success"}],
    "deployStatus": "success"
  },
  "deploy": {
    "status": "success",
    "runId": "1778665915"
  },
  "lastUpdated": "2026-05-13T17:52:03Z"
}

CI 日志折叠与 ANSI 颜色

  • 构建日志按步骤自动折叠(▶/▼ 切换)
  • ANSI 颜色转义码自动转换为 HTML 颜色(红/绿/黄等)
  • 实时轮询更新(3秒间隔)

Python 项目 UV 支持

检测到 uv.lock 或 pyproject.toml 中包含 tool.uv 时自动使用 uv sync:

{"steps": [
  {"name": "UV Sync", "command": "uv sync || uv pip install -e . || true"},
  {"name": "Test", "command": "uv run pytest || true"}
]}

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 3

Native requirements
3 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
cors
Environment
{
  "local_name": "cors",
  "alias": false,
  "peer_metadata": null
}
^2.8.5runtime
express
Environment
{
  "local_name": "express",
  "alias": false,
  "peer_metadata": null
}
^4.18.2runtime
js-yaml
Environment
{
  "local_name": "js-yaml",
  "alias": false,
  "peer_metadata": null
}
^4.1.1runtime

Distribution files

1 collected
Distribution 1

Source distribution

Source file
Checksums from source
{
  "shasum": "0f080235d45eaa2a34cc49f4017964659821c672",
  "tarball": "https://registry.npmjs.org/@076lik/git-panel/-/git-panel-2.2.8.tgz",
  "fileCount": 18,
  "integrity": "sha512-ji8IniD6Klpth6PJaQlMEP5UAQJs397SZXJAkD1mdRj7Z42Bn2P+U1aBrF9s60rRjdgDZd0XIH4+ES3rkir5qg==",
  "signatures": [
    {
      "sig": "MEYCIQDQ8Sk1lXXRgmusoD5o5/DH0IjHOV02NJYAd8rxBYZR4QIhAONMZvZDE2J8/42M3pDYgrIFVUaJBa6ale93aEfAOy9B",
      "keyid": "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
    }
  ],
  "unpackedSize": 1597411
}

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 22:03 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:3562cfa204f6e156f9f4f0a4d65cc98b118c1c1954c46d572ba7ceb23dae3e32

Other collected versions

3.2.121 Sept3.2.021 Sept3.0.116 Sept3.0.016 Sept2.2.98 Jun2.2.78 JunView all collected versions →