提交与备份纪律
来源:
intranet-tunnel/docs/mobile-parallel-work.md→## 五、提交纪律(两个会话都适用)(原文 460 字符)
五、提交纪律(两个会话都适用)
# 🟦 移动端会话
git -C H:\Works\intranet-tunnel add mobile/ docs/mobile-parallel-work.md
git -C H:\Works\intranet-tunnel commit -F <仓库外的提交信息文件> # 多行必须用 -F
# 🟥 服务端会话
git -C H:\Works\intranet-tunnel add server/ docs/mobile-api-contract.md .env.example- 提交前用
git status --short确认暂存区只有自己目录的文件。 - 提交信息文件写到仓库外(如
H:\Works\.recover\),避免与对方争抢同一个临时文件。 - 索引冲突(
index.lock)时重试即可,不要删锁文件。 - 双方都不要
git commit -a。
来源:
AGENTS.md→## 版本控制与备份(2026-09-12 起)(原文 5196 字符)
版本控制与备份(2026-09-12 起)
本项目的源码受 git 保护,且有本地裸仓库自动备份。 这是对「目录被清理」那次事故的制度性防护。
- 仓库:
H:\Works\intranet-tunnel(main分支) - 两个远程,都已配好:
| remote | 位置 | 用途 |
|---|---|---|
backup | H:\Works\backup\intranet-tunnel.git(裸仓库) | 本地离线兜底 |
gitea | http://<内网IP>:3234/sushike/intranet-tunnel.git(NAS 上的 Gitea,私有) | 异地兜底 |
post-commit钩子会在每次提交后自动 push 到这两个远程,无需手动操作。
钩子内容(.git/hooks/post-commit):
git push backup main --quiet 2>/dev/null || true
git push gitea main --quiet 2>/dev/null || true- Gitea 认证走 Windows 凭据管理器(
git credential approve写入),
token 不在 .git/config 里,remote URL 不含凭据。
- 本机未安装
make,Makefile 里的同名目标只在装了 make 的环境可用。本机请直接用 git:
# 备份(提交 + 推送;钩子通常已自动推送,这条用于确认)
git -C H:\Works\intranet-tunnel add -A
git -C H:\Works\intranet-tunnel commit -F <提交信息文件>
git -C H:\Works\intranet-tunnel push backup main
# 查看状态与远程
git -C H:\Works\intranet-tunnel status --short
git -C H:\Works\intranet-tunnel remote -v
# 从备份恢复(输出到新目录)
git clone H:\Works\backup\intranet-tunnel.git H:\Works\restored- Makefile 中保留了
backup/backup-init/restore/status四个目标,
便于在 Linux 或有 make 的机器上使用。
约定(务必遵守):
- 改完代码就提交,不要攒着。钩子会自动同步到备份仓库。
.env及含凭据的变体绝不入库。真实配置只留本机;需要新增配置项时,
同时更新对应的 .env.example(脱敏模板)并提交。
- 已忽略:
.env、**/.env、client/.env.*(放行*.example) - 保留入库:
.env.example、server/.env.docker(纯占位模板)
- **
release/*.tar、release/*.zip(约 246 MB)不入库** —— 发布产物可随时重新生成,
且超过 GitHub 单文件 100 MB 限制。
frontend/dist只保留gitkeep。//go:embed all:frontend/dist要求目录存在,
删掉占位文件会导致新克隆的仓库无法编译(client 与 server 两侧都要有)。
- 提交信息多行时用
git commit -F <文件>,不要用-m(PowerShell 下转义易出错)。 - 添加 GitHub 远程后,务必先确认仓库是 Private,再决定是否补推历史:
git remote add origin <邮箱已脱敏>:<用户名>/<仓库>.git && git push -u origin main
- 访问内网 Git 服务前必须绕过系统代理(2026-09-12 实测):
本机 git 全局配了 http.proxy=http://127.0.0.1:7899(翻墙代理)。该代理未运行时, 访问内网 Gitea 会报 Failed to connect to 127.0.0.1:7899 over proxy 127.0.0.1 —— 注意报错里出现的是 代理地址而不是 Gitea 地址,很容易误判成「Gitea 挂了」或「网络不通」。
⚠️ git config <key> "" 对本机这个 Git 版本无效(实测:命令返回成功, 但 git config --global --get-regexp proxy 里根本看不到这个键,等于没设; 项目级同样无效)。不要用这个写法。
有效做法:直接写 .git/config(只影响本项目,不动全局代理):
[http "http://<内网IP>:3234"]
proxy =写完用这两条确认是否真的读到:
git config --show-origin --get-regexp 'proxy' # 应出现 file:.git/config 那一行
git ls-remote gitea # 应能列出 refs,不再报 127.0.0.1:7899已额外设置用户级 NO_PROXY=<内网IP>,127.0.0.1,localhost 作为兜底。
排查要点:判断"配置有没有生效"必须用 --show-origin,不要只看命令退出码 —— 空值配置的写入失败是无提示的。
- 镜像归档必须覆盖 compose 里用到的全部镜像(2026-09-12 实测踩到):
nginx 极易被漏掉——它不在项目代码里,只出现在 compose 的 image: 字段, 而服务器上通常没装过 nginx(80/443 也就起不来)。 判据:Select-String -Path docker-compose.yml -Pattern '^\s+image:' 列出全部 image: 行再按 tag 去重,不要凭印象(db-backup 复用 postgres:16-alpine)。 校验归档内容(docker save 的 tar 首个条目就是 manifest.json):
tar -xf <tar> -C <临时目录> manifest.json
(Get-Content manifest.json -Raw | ConvertFrom-Json).RepoTags- 发布新版本到 Gitea(已验证流程):用 Node 脚本,不要用
curl.exe(理由见下一条)。 - 取 token(不打印、不落盘):
"protocol=httpnhost=<内网IP>:3234nn" |
git credential fill → 把 password= 那一行赋给 $env:GITEA_TOKEN`, 必须在同一个 PowerShell 调用内紧接着跑脚本。
- 创建/更新 Release:
node H:\Works\.recover\create-release-1xx.js <正文md> <tag>
—— 正文从文件读,绕开 PowerShell → 原生程序的转义与中文乱码问题。
- 上传附件:
node H:\Works\.recover\upload-assets.js <releaseId> <文件...>。 - 附件的下载地址是
browser_download_url(形如/attachments/<uuid>);
API 的 /releases/{id}/assets/{asset_id} 只返回 JSON 元数据、不是文件内容 —— 用它验证"能否下载"会得到 200 + 273 字节 JSON,误判为附件异常。
- 该 Gitea 只监听 HTTP(
https://<内网IP>:3234连不上)。
若要启用其内置容器注册表(/v2/ 已启用,401 属正常),必须先把 <内网IP>:3234 加进 ~/.docker/daemon.json 的 insecure-registries 并重启 Docker Desktop(会中断全部容器)——2026-09-12 评估后决定暂不做。
- 上传附件不要用 curl(2026-09-12 实测变更):
curl.exe -s --noproxy '*' -F "attachment=@<路径>" ... 在本机返回 HTTP 000 (连接都没建立,且 0.0 秒就返回),同一台机器上换成 Node 的 fetch + FormData + Blob 一次就通(148.8 MB 用时 2.7 秒)。脚本:H:\Works\.recover\upload-assets.js (用法 node upload-assets.js <releaseId> <文件...>)。 判据:HTTP 000 是"请求没发出去",不是服务端拒绝,不要往认证或路径上排查。 历史上这条命令是能用的,所以不要凭印象认为它一定可行——先用 1 个小文件试。
- GCM 主机探测延迟:
credential.helper是 system 级的manager,
推送时会尝试探测主机类型,超时 2 秒并出现 warning: auto-detection of host provider took too long。 已设 credential.autoDetect=false 与 credential.http://<内网IP>:3234.provider=generic 消除。
- Git Credential Manager 的
credential.helper在 system 级(D:/Git/etc/gitconfig为manager)。
用 git credential approve 可把凭据写入 Windows 凭据管理器,避免 token 落进 .git/config:
"protocol=http`nhost=<host>:<port>`nusername=<用户名>`npassword=<token>`n`n" | git credential approve恢复演练(已验证可行):
git clone H:\Works\backup\intranet-tunnel.git H:\Works\restored
cd H:\Works\restored
go build ./shared/... ./server/... ./client/... # 直接编译通过
# 注意:.env 不在版本库里,需从 .env.example 复制并填入真实值