# git-init 参考 SKILL.md 未覆盖的细节。Agent 只在需要时阅读本文件。Gitea 见 [gitea.md](gitea.md);克隆/拉取/分支/合并见 [workflows.md](workflows.md)。 ## 中文提交规范 所有提交信息必须使用中文。 格式: ``` 类型: 描述 Co-authored-by: 姓名 <邮箱> ``` 每次提交**必须**带 `Co-authored-by`(Git trailer)。主体与 trailer 之间空一行。 - 默认:档案中的 `userName` / `userEmail`(例如 `Co-authored-by: 旅行呀~ `) - 额外合作者:档案字段 `coAuthors`(`store-profile.ps1` 可追加 `Name `) - 生成完整说明:`emit-commit-message.ps1 -Subject "类型: 描述"` 示例: ``` 初始化: 完成项目Git配置 Co-authored-by: 旅行呀~ ``` ``` 新增: 添加用户模块 Co-authored-by: 旅行呀~ ``` 禁止: ``` update fix test 修改一下 ``` 后续提交作者(`git` Author)必须为本地档案中的 `姓名 <邮箱>`,且说明里含对应 `Co-authored-by`。每次提交必须包含清晰描述,例如: ``` 新增: 添加支付接口 Co-authored-by: 旅行呀~ ``` 签名提交使用 `git commit -S`。仓库 local 配置 `commit.gpgsign=true` 后,普通 `git commit` 也会签名。 ## 日常提交 每次提交都走 `prepare-commit.ps1`,不要重新 `git init`。 1. `prepare-commit.ps1` 把档案中的 `user.name` / `user.email` 写到**当前仓库**,并打开 `commit.gpgsign`;输出 `co_authored_by=` 2. `signing=missing` 时再跑 `ensure-gpg.ps1`,写入 `user.signingkey` 3. `git status` / `git diff` / `git log -5` 后再写中文 `类型: 描述` 4. `assert-no-secrets.ps1` 失败则不得提交匹配路径 5. 后续提交只暂存相关文件,不要默认 `git add -A` 6. 用 `emit-commit-message.ps1` 生成带 `Co-authored-by` 的说明,再 `git commit -S -m ...` 7. `git log -1 --format=%B` 确认含 `Co-authored-by:` 8. 用户没说推送就不要 `git push` 无变更时不要空提交。 ## 日常推送 每次推送都走 `prepare-push.ps1`,不要重新初始化。 1. 从 `origin` 解析 URL;HTTPS 静默注入 Token;SSH 则 `ssh-add`(不生成新密钥、不打印公钥) 2. 当前分支无上游:`git push -u origin HEAD` 3. 已有上游:`git push` 4. 禁止 `--force`,除非用户明确要求 5. URL 里若带账号密码,脚本输出会打码,Agent 也不得把完整带密 URL 发到对话里 ## Windows SSH 不要使用: ```bash eval "$(ssh-agent -s)" ``` Windows 使用 OpenSSH 服务: ```powershell Get-Service ssh-agent Set-Service ssh-agent -StartupType Manual Start-Service ssh-agent ssh-add $env:USERPROFILE\.ssh\id_ed25519 ``` `ensure-ssh.ps1` 会尝试启动服务并 `ssh-add`。`Set-Service` / `Start-Service` 在服务被禁用时可能需要管理员权限;失败时仍展示公钥,让用户手动添加。 公钥路径:`.pub`。只把公钥贴到 **Gitea → 设置 → SSH / GPG 密钥**。私钥不得出现在聊天或仓库里。 测试(推荐脚本,支持自建端口): ```powershell powershell -NoProfile -ExecutionPolicy Bypass -File "/test-ssh.ps1" -RemoteUrl "git@git.example.com:owner/repo.git" powershell -NoProfile -ExecutionPolicy Bypass -File "/test-ssh.ps1" -RemoteUrl "ssh://git@git.example.com:2222/owner/repo.git" ``` 手写等价命令: ```powershell ssh -T git@git.example.com ssh -p 2222 -T git@git.example.com ``` Gitea 成功时常见输出含 `Hi there` / `successfully authenticated` / `Welcome to Gitea`,退出码可能为 1。无 shell 权限是正常的。 完整菜单与 Token 步骤见 [gitea.md](gitea.md)。 若 `ssh-keygen` 不存在:安装 Git for Windows 或 Windows OpenSSH 可选功能。 ## GPG 需要本机 `gpg`(Gpg4win 或 Git 自带)。`ensure-gpg.ps1` 会按档案姓名/邮箱查找已有密钥;没有则 batch 生成 Ed25519,失败再回退 RSA 4096。生成密钥使用 `%no-protection`(无口令),便于 Cursor 非交互签名。若用户需要口令保护,应自行用 `gpg --full-generate-key` 创建,再把 key id 交给本流程。 列出密钥: ```powershell gpg --list-secret-keys --keyid-format LONG ``` Git 配置(仅当前仓库): ```powershell git config user.signingkey KEY_ID git config commit.gpgsign true ``` 将公钥添加到 **Gitea → 设置 → SSH / GPG 密钥**。否则网页上可能不显示已验证,但本地签名仍然有效。详见 [gitea.md](gitea.md)。 ## Token 与凭据 Token 只存在 `%USERPROFILE%\.git-skills\token.dpapi`,DPAPI 绑定当前 Windows 用户。换机器或换用户无法解密。 - 写入:用户本机运行 `store-token.ps1`(隐藏输入) - 状态:`token-status.ps1` → `present` / `missing` / `invalid` - 注入:`inject-credential.ps1 -RemoteUrl ` 通过 `git credential approve` 交给 Git Credential Manager,stdout 不含 Token 全局可设: ```powershell git config --global credential.helper manager ``` HTTPS 远程:用户名为档案中的 `gitUsername`(Gitea 登录名),密码为访问令牌。非默认端口会写入 GCM(如 `host=git.example.com:3000`)。SSH 远程:推送走 SSH 密钥;脚本仍会为同一主机注入 HTTPS 凭据(不含 SSH 端口)。详见 [gitea.md](gitea.md)。 ## 故障排查 | 现象 | 处理 | | --- | --- | | `profile=missing` | 用户本机运行 `store-profile.ps1` | | `token=missing` / `invalid` | 用户本机运行 `store-token.ps1`(`invalid` 表示无法用当前用户 DPAPI 解密) | | `git_username_missing` | 重新运行 `store-profile.ps1` 并填写 HTTPS 用户名 | | `git_credential_approve_failed` | 确认已安装 Git for Windows / GCM,并设置 `credential.helper=manager` | | `ssh_keygen_missing` | 安装 OpenSSH 或 Git for Windows | | `ssh_agent=error` 或 `ssh_add=failed` | 以管理员启用 `ssh-agent` 服务,或用户手动 `ssh-add` | | `Permission denied (publickey)` | 把 `public_key=` 贴到平台后再 `ssh -T` | | `gpg_missing` | 安装 [Gpg4win](https://www.gpg4win.org/) 并重新打开终端 | | `gpg_generate_failed` | 检查 gpg 是否可用;或用户交互生成后再跑 `ensure-gpg.ps1` | | push 认证失败(HTTPS) | 确认 Token 对应该 host 且未过期;重新 `store-token` + `inject-credential` | | 已有 `origin` | 不要改 remote;改为提交/推送或让用户决定 | | `git log --show-signature` 无签名 | 确认 `commit.gpgsign=true` 且用了 `-S`;GPG 密钥存在 | | `not_a_git_repo` | 先走初始化,或确认当前目录是仓库 | | `remote_missing` | 用户提供 URL 后 `git remote add origin` | | `secret_paths` | 从暂存区移除脚本列出的路径后再提交 | | `ssh_key_missing`(日常推送) | 走初始化 SSH,或用户指定已有密钥路径 | | `test-ssh` 失败 | 公钥是否已加到 Gitea;URL 端口是否正确;本机是否已接受 host key | | HTTPS 自建端口失败 | 确认 URL 含 `:3000` 等端口;GCM 的 host 应为 `host:port` | | 灰色开锁 / 找不到此签名对应的密钥 | 按官方:库中无可用密钥。完成 Gitea **验证**;对齐 `signingkey`;邮箱一致;见 [gitea.md](gitea.md) | | GPG 验证签名不被接受 | 必须用 `echo "TOKEN"`(有换行);用 `verify-gpg-challenge.ps1`,勿用 SSH 的 `echo -n` | | SSH 验证签名不被接受 | 必须用 `echo -n`(无换行);用 `verify-ssh-challenge.ps1` 或页面上的 PowerShell/`cmd` 提示 | ## 硬限制 - 不 force push - 不修改已有 remote - 不把 Token、私钥、`.dpapi` 写入仓库 - 不把 Token 放进命令行参数或对话 - 不修改全局 `user.name` / `user.email`