
本文为 AtomGit 码动四季·开源同行征稿活动参与文章难度等级⭐⭐⭐3/5前置知识Git 基础、grep 正则、基础 CI 概念今年 9 月我用 AI 辅助开发做了一个桌面工具——仓衡 RepoBalance一个给 Git 仓库做体检的应用用 Rust 写检查器插件扫出大文件、密钥残留、提交规范问题这些仓库健康度指标Tauri 2 Vue 3 做壳20 多天迭代出可打包发布的版本。本地能跑、demo 能演之后下一步就是开源。但本地能跑和敢给外人 clone之间我给自己设了四道关合规、结构、历史、发布。真正动手过这四道关之后我才发现——哪怕是一个只有 24 次提交的小仓库坑一点不少.gitignore没盖住的中间产物、git 历史里躺着本机绝对路径的原型文件、CI 里 token 权限差一种就发不出 Release。这篇文章完整复盘这次开源化体检四道关各查什么、用什么命令查、我真实踩过的三个坑。如果你也有一个自己用没问题、开源就心虚的代码仓库这篇就是给你的检查清单。一、先想清楚本地可用和开源合格差了四道关本地仓库的目标读者只有一个人——我自己。我知道哪些目录是构建产物、哪个文件里嵌着我的机器路径、哪些提交只是给自己看的备忘。开源之后读者换成了陌生人评价标准就完全变了。我把这个差距整理成四道关后面每一段对应一道关的真实操作敏感信息清理三件套gitignore 治理git 历史脱敏CI 打包双平台验证本地仓库135 个跟踪文件 / 6363 行代码合规关结构关历史关发布关开源仓库任何人可 clone四道关的顺序是有讲究的先做合规内容层面再做结构仓库骨架层面然后处理历史时间层面最后才是发布分发层面。反过来做的代价是返工——先搭发布流程再回头扫敏感信息每扫出一批命中打包脚本、README 截图就得跟着改一遍。这个顺序教训我在上一个内容仓库的开源改造里已经吃过一次这次直接按对的顺序来。二、合规关先知道有什么再谈删什么脱敏最忌讳的是凭感觉删。我的做法是先把敏感模式定义清楚然后全量扫描拿到真实命中数再逐类处理。四类敏感模式对应的扫描命令如下这几条命令本身可以直接复用# 1. 内网 IP 与内网地址10.x / 172.16-31.x / 192.168.xgrep-rEnhttps?://(10|172\.(1[6-9]|2[0-9]|3[01])|192\.168)\.[0-9]{1,3}\--include*.rs--include*.ts--include*.vue--include*.md\--exclude-dirtarget --exclude-dirnode_modules.hits_intranet_ip.txt# 2. 本机绝对路径泄露用户名和目录结构grep-rEn/Users/[a-zA-Z0-9_]/\--exclude-dirtarget --exclude-dirnode_modules.hits_local_path.txt# 3. 邮箱与个人联系方式grep-rEn[a-zA-Z0-9._%-][a-zA-Z0-9.-]\.(com|cn|net)\--exclude-dirtarget --exclude-dirnode_modules --exclude-dir.git.hits_email.txt# 4. 硬编码密钥的高危形态辅助人工确认不能只靠它grep-rEin(api[_-]?key|secret|token|password)\s*[:]\s*[\][^\]{8,}\--include*.rs--include*.ts--include*.yml.hits_secret.txt扫出来的真实结果敏感类型命中文件数典型样本处理方式内网 IP 链接0—新写的代码没有测试环境地址无本机绝对路径1docs/prototype/下 609 行的 HTML 原型文件里面嵌着我机器的绝对路径见下文历史与工作区分别处理个人邮箱工作区 0.git/日志里有属于正常 git 记录不算泄露排除.git目录再扫硬编码密钥0CI 配置里的凭据全部走变量注入保持现状工作区很干净但历史不干净。这就是下一节历史关要讲的——git log -S一扫那个 HTML 原型文件的初稿版本就现形了。合规关还有一个代码仓库特有的项.gitignore是否真的把中间产物挡在了库外。我git ls-files数了一遍跟踪文件 135 个target/Rust 构建产物本地实际占 500MB和node_modules/均为 0 个跟踪文件——这一项过关。开源仓库里混进一个构建产物目录比泄露一个路径更让 clone 的人困惑。脱敏不是扫一遍就完事。我实际执行了两轮第一轮按模式清单全量处理第二轮隔了一天用相同命令复扫确认零新增命中。所以合规关的验收标准是连续两轮扫描零新增命中而不是扫过一遍了。有零新增第一轮全量扫描按初始模式清单逐类处理脱敏隔 24h 复扫新增命中?分析变体写法追加模式规则验收通过连续两轮零命中三、结构关三件套盘点与 gitignore 治理3.1 协作三件套缺一样补一样开源仓库没有这三样东西外人 clone 之后的第一反应是然后呢README.md回答三个问题——这个工具是什么给 Git 仓库做体检的桌面应用附功能演示 GIF、怎么跑起来pnpm installcargo tauri devCI 打包流程写明、能不能商用Apache-2.0指向 LICENSELICENSE开源前就位选型过程为什么是 Apache-2.0 而不是 MIT写在 02 号文章里CONTRIBUTING.md初始版本缺失开源前补齐——哪怕暂时只有一个人维护也要写清楚 issue 怎么提、PR 需要过哪些检查、commit message 必须符合 Conventional Commits03 号文章的流水线依赖这一点。盘点命令一行搞定缺什么一目了然lsLICENSE README.md CONTRIBUTING.md CHANGELOG.md3.2 AI 协作入口的收敛这个仓库是用 AI 编程助手按投喂话术 每日验收的节奏开发出来的过程中沉淀了一份AGENTS.md项目指令——里面是构建命令、验收标准、代码约定。开源前我把它做了一轮脱敏和去上下文化删掉只有我自己看得懂的阶段性备忘保留任何人 clone 下来也能按它构建和验收的部分。这件事的额外收益是任何 AI 编程工具接手这个仓库时都有了统一的上下文入口。3.3 gitignore 是结构关的隐形主角代码仓库和内容仓库在结构关的重心完全不同内容仓库操心图片体积和目录组织代码仓库操心中间产物隔离。我的检查方法是把本地目录大小和跟踪文件数对个账du-sh.# 本地 576MB含 target/、node_modules/gitls-files|wc-l# 跟踪 135 个文件本地 576MB、跟踪文件只有 135 个——说明构建产物全部被.gitignore正确挡住了。反过来如果这两个数字比例失衡第一件事就是把产物目录补进.gitignore再git rm -r --cached清掉已跟踪的产物。四、历史关git 历史比工作区更危险这是整次体检里我认知刷新最大的一关也是这次唯一真正扫出问题的一关。工作区脱敏得再干净git 历史里的每一次提交都是可以 checkout 回来的。# 在全部历史中搜索敏感内容不只查最新版本gitlog--all-S/Users/--onelinegitlog--all-S192.168.--oneline第一条命令扫出了一个真实命中docs: 添加仓衡 HTML 原型文件那次提交——609 行的 HTML 原型里嵌着我的机器绝对路径。工作区后来已经处理但初稿还躺在历史里。任何拿到仓库的人 checkout 到那个 commit路径原样奉还。处理方案对比方案做法代价适用保留全量历史 filter-repo 清洗git filter-repo --replace-text替换历史中的敏感串历史哈希全部改变需 force push历史有价值、想保留演进痕迹重建单 commit 历史--orphan分支重新提交旧历史丢弃丢掉全部演进记录历史里敏感内容多且分散折中保留近期、裁剪远期shallow 重新打标签操作复杂两套历史难对齐不推荐维护成本高这个仓库的实际情况是24 次提交、单作者、开发期只有三周。历史本身没有考古价值不是需要对外承诺兼容性的框架代码而需要清洗的只有一个文件的一个提交。我最终选了filter-repo 定点替换保留演进历史24 次提交本身是这个项目开发方法论的证据只把历史里的本机路径串替换掉然后 force push 到两个远端。替换后再跑一遍git log -S验证双零命中。一个必须诚实交代的细节清洗会导致历史哈希变化如果有别人已经 clone 过旧哈希他们的本地历史会和远端分叉。开源首日就做这件事代价最小——拖到有 star 有 fork 之后清洗成本会指数级上升。历史脱敏要赶在有人关心你的历史之前做完。五、发布关CI 打包、体积账与最后的检查5.1 发布通道双平台 自动打包发布关要回答两个问题发到哪里、谁来做安装包。发到哪里GitHub 为主站Actions 生态成熟桌面应用打包 workflow 现成AtomGit 做国内镜像国内用户 clone 快这也是参加本次征稿的载体谁做安装包CI。GitHub Actions 上配了两条 workflow——一条跑测试和 Rust/前端构建检查一条打 Windows/macOS 安装包并发布 ReleaseAtomGit 侧用ci/atomgit-pipeline.yml做同步构建。tag 触发git pushGitHub Actionslint test桌面打包 workflowWindows / macOS 安装包GitHub Release自动附安装包AtomGit pipeline同步构建验证安装包/源码双渠道国内用户走 AtomGit5.2 体积账代码仓库的幸运代码仓库在体积上天然比内容仓库幸运Rust 源码 3746 行、前端 2617 行全部源码加起来不到 7MBclone 秒级完成。真正的大头——target/构建目录500MB和node_modules/——都在.gitignore之外。git count-objects一看 pack 只有 KB 级无需 LFS、无需浅克隆。这也反过来说明 3.3 节那个对账动作的必要性只要有一个产物目录漏进跟踪区clone 体积就会从 MB 级跳到百 MB 级。5.3 发布前最后一轮验证# 发布前的最终验证清单三条全绿才 pushgrep-rEn192\.168\.|/Users/--exclude-dirtarget --exclude-dirnode_modules --exclude-dir.git.\echoFAIL: 敏感残留||echoPASSgitlog--all-S/Users/--oneline|wc-l# 应为 0清洗后lsLICENSE README.md CONTRIBUTING.md# 三件套齐全六、三个真实踩坑1. CI 机器人权限不足tag 打了 Release 没建现象桌面打包 workflow 跑完tag 已推上去Release 创建那一步失败——仓库陷入有 tag 无 Release的脏状态下一次运行还把 tag 当成已发版。根因默认GITHUB_TOKEN只有读权限创建 Release 需要contents: write没显式授予。解决workflow 里显式声明permissions: contents: write并养成发版后去 Release 页对账的习惯git tag -l与平台 Release 列表逐个核对。教训发版动作需要 tag、Release、push 三种写权限权限是 CI 发版的第一故障源——一次配齐好过每次 403 再补。2. Windows 打包productName 踩了安装包兼容性现象Windows 安装包打出来后安装/卸载行为异常桌面应用在 Windows 侧的元数据不对。根因Tauri 配置里的productName取值与 Windows 安装器对产品名的预期不兼容macOS 侧没暴露这个问题测试只在一台 Mac 上跑过。解决productName改为RepoBalanceCI 的 Windows 打包 job 补进验收清单两个平台都要打包验证过才能发 Release。教训桌面应用开源的验收单位是每个目标平台一个安装包不是我的机器上能跑——单平台验证过的发布脚本等于没验证。3. CI 里二进制路径本地与打包环境不一致现象新增桌面打包 workflow 后第一次运行就失败CI 找不到rb二进制——本地cargo build产物路径和打包 job 的工作目录对不上。根因workflow 手写的二进制路径沿用了我本地目录结构的假设CI 环境的 target 目录层级不同。解决CI 里改为从cargo build的标准输出位置解析路径并在 PR 模板里加一条新增路径引用必须在 CI 跑绿后再合并。教训一切写死本机路径假设的脚本开源的那一刻都是定时炸弹——CI 是检验仓库是否自包含的最诚实测试。七、效果与边界整个开源化体检的执行时间线四个阶段累计约三天业余时间节奏可参考指标体检前体检后工作区敏感命中1 个文件本机路径0两轮扫描零新增git 历史敏感内容1 个提交可回溯到含路径的原型初稿filter-repo 清洗后git log -S双零命中协作入口有 LICENSE/README缺 CONTRIBUTING三件套齐全发布通道本地手工打包GitHub Actions 自动打包 ReleaseAtomGit 镜像clone 体积未验证pack KB 级秒级 clone适用边界也要说清楚这套四道关流程的样本是小型代码仓库单人、单仓、20 余次提交。它和内容型仓库的开源改造重心不同——内容仓库的主战场是图片体积、占位符和目录组织代码仓库的主战场是 gitignore 治理、依赖许可证审计02 号文章的主题和 CI 密钥泄露。仓库越大、历史越长历史关的清洗成本越高历史脱敏要趁早这条对所有类型都成立。八、总结复盘下来这次体检最值得说的三个判断第一小仓库不等于低风险。24 次提交照样扫出了历史里的本机路径——敏感信息的暴露面积和仓库规模无关只和有没有认真扫过有关。第二CI 是开源合格性的试金石。三件套齐不齐、路径自不自包含、权限配没配对本地怎么检查都有盲区推上 CI 跑一遍全部现形。第三历史脱敏要赶在有人关心你的历史之前。开源首日清洗历史代价是一次 force push有了 star 和 fork 之后同样的清洗要面对无数分叉的本地副本。这个仓库现在已在 GitHub 和 AtomGit 双平台开源发版流水线03 号、依赖与 issue 治理04 号都跑在这个仓库上。下一篇讲开源改造里最容易被敷衍但后果最重的一步许可证怎么选——为什么这个仓库最终选了 Apache-2.0。真实性声明本文所有数据135 个跟踪文件、Rust 3746 行 前端 2617 行、24 次提交、扫描命中数、本地 576MB 目录体积均来自仓库实际扫描与 git 历史统计扫描命令文中已给全可自行复现验证。案例仓库atomgit.com/dickeryang/repo-balanceGitHub 同名镜像。参考资源git filter-repo 官方文档AtomGit 平台文档GitHub Docs: Removing sensitive data from a repository专栏导航上一篇无下一篇开源许可证选择与合规落地实战如果本文对你有帮助欢迎点赞、收藏、转发。有任何问题或建议请在评论区留言交流。行文仓促定有不足之处欢迎各位朋友在评论区批评指正不胜感激。