+222
@@ -0,0 +1,222 @@
|
||||
# git-init 使用文档
|
||||
|
||||
在 Cursor 里用本 Skill 完成完整 Git 流程。默认远程为 **Gitea**(自建或公网实例):初始化、每次签名提交、每次推送,以及克隆、拉取、分支、合并、标签、暂存。令牌只存在本机并加密,不会出现在对话或仓库里。
|
||||
|
||||
配套阅读:
|
||||
|
||||
- [架构.md](架构.md) — 组件、数据流、流程图
|
||||
- [Gitea 说明](../.cursor/skills/git-init/gitea.md) — URL、Token、SSH、GPG 菜单
|
||||
|
||||
## 你需要准备什么
|
||||
|
||||
| 时机 | 你提供什么 | 不要提供什么 |
|
||||
| --- | --- | --- |
|
||||
| 本机一次 | 作者档案 + Gitea 访问令牌(本机终端) | 不要在 Cursor 聊天里粘贴 Token |
|
||||
| 初始化 | Gitea 仓库 URL;可选 SSH/GPG 偏好 | 不要把私钥或 Token 发给 Agent |
|
||||
| 日常提交 / 推送 | 说「提交」「推送」或「提交并推送」 | 不必再给 Token |
|
||||
| 克隆 / 拉取 | Gitea URL 或「拉取远程」 | 不必再给 Token |
|
||||
|
||||
默认作者(可在档案里改):`旅行呀~` `<travelxiao@qq.com>`。
|
||||
|
||||
提交信息必须是中文:`类型: 描述`(`初始化` / `新增` / `修复` / `优化` / `文档`)。
|
||||
|
||||
**每次提交还必须带 `Co-authored-by`**(与档案作者一致,可另加合作者):
|
||||
|
||||
```
|
||||
类型: 描述
|
||||
|
||||
Co-authored-by: 旅行呀~ <travelxiao@qq.com>
|
||||
```
|
||||
|
||||
由 `emit-commit-message.ps1` 自动拼上。额外合作者在 `store-profile.ps1` 里按 `Name <email>` 追加,写入档案的 `coAuthors`。
|
||||
|
||||
## Gitea 地址示例
|
||||
|
||||
```
|
||||
https://git.example.com/owner/repo.git
|
||||
https://git.example.com:3000/owner/repo.git
|
||||
git@git.example.com:owner/repo.git
|
||||
ssh://git@git.example.com:2222/owner/repo.git
|
||||
```
|
||||
|
||||
HTTPS:用户名 = Gitea 登录名,密码 = **访问令牌**(设置 → 应用 → 生成新令牌)。
|
||||
SSH / GPG:设置 → SSH / GPG 密钥。
|
||||
|
||||
## 安装
|
||||
|
||||
在本仓库根目录:
|
||||
|
||||
```powershell
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1
|
||||
```
|
||||
|
||||
效果:
|
||||
|
||||
- 项目级:`.cursor/skills/git-init`(本仓库直接可用)
|
||||
- 个人级:`%USERPROFILE%\.cursor\skills\git-init`(所有项目可用)
|
||||
|
||||
不要安装到 `~\.cursor\skills-cursor\`。改了 Skill 源码后重新跑一次 `install.ps1`。
|
||||
|
||||
## 本机一次配置
|
||||
|
||||
在**自己的 PowerShell**里运行(不要在对话里贴 Token):
|
||||
|
||||
```powershell
|
||||
$scripts = "$env:USERPROFILE\.cursor\skills\git-init\scripts"
|
||||
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "$scripts\store-profile.ps1"
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "$scripts\store-token.ps1"
|
||||
```
|
||||
|
||||
- `store-profile`:姓名、邮箱、**Gitea 用户名**、SSH 私钥路径;可选追加额外 `Co-authored-by`(`Name <email>`)
|
||||
- `store-token`:隐藏输入 **Gitea 访问令牌**,DPAPI 加密到 `%USERPROFILE%\.git-skills\token.dpapi`
|
||||
|
||||
检查(可在 Cursor 里跑,不会打印 Token):
|
||||
|
||||
```powershell
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "$scripts\profile-status.ps1"
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "$scripts\token-status.ps1"
|
||||
```
|
||||
|
||||
`token-status` 只会出现 `present` / `missing` / `invalid`。
|
||||
|
||||
## 在 Cursor 里怎么说
|
||||
|
||||
把下面整句发给 Agent(把 URL 换成你的 Gitea 仓库)。
|
||||
|
||||
### 初始化
|
||||
|
||||
```text
|
||||
用 git-init 初始化这个仓库,远程是 git@git.example.com:owner/repo.git
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```text
|
||||
用 git-init 初始化,远程是 https://git.example.com:3000/owner/repo.git
|
||||
```
|
||||
|
||||
会:`git init`、写本地作者、加 origin、注入凭据、SSH/GPG、补 `.gitignore`、中文签名提交、推送 `main`。
|
||||
|
||||
### 日常提交
|
||||
|
||||
```text
|
||||
按 git-init 提交这些改动
|
||||
```
|
||||
|
||||
### 日常推送
|
||||
|
||||
```text
|
||||
推送到 Gitea
|
||||
```
|
||||
|
||||
### 提交并推送
|
||||
|
||||
```text
|
||||
提交并推送
|
||||
```
|
||||
|
||||
### 克隆
|
||||
|
||||
```text
|
||||
用 git-init 克隆 https://git.example.com/owner/repo.git
|
||||
```
|
||||
|
||||
### 拉取
|
||||
|
||||
```text
|
||||
拉取远程更新
|
||||
```
|
||||
|
||||
默认 `--ff-only`。历史分叉时会停下问你,不会强推。
|
||||
|
||||
### 分支 / 合并 / 查看
|
||||
|
||||
```text
|
||||
基于当前分支新建 feature/login 并切过去
|
||||
把 feature/login 合进 main
|
||||
现在 git 状态怎么样
|
||||
```
|
||||
|
||||
更多例句见 [examples.md](../.cursor/skills/git-init/examples.md)。
|
||||
|
||||
## 能力一览
|
||||
|
||||
| 路径 | 做什么 | 认证 |
|
||||
| --- | --- | --- |
|
||||
| Init | 建库、远程、SSH、GPG、首次提交并推送 | Gitea Token + SSH |
|
||||
| Commit | 每次中文签名提交 + `Co-authored-by` | 本地 GPG |
|
||||
| Push | 每次推送当前分支 | Token 或 SSH |
|
||||
| Clone | 克隆 Gitea 仓库 | `prepare-auth` |
|
||||
| Sync | fetch / pull --ff-only | `prepare-push` |
|
||||
| Branch / Merge / Tag / Stash / Inspect | 本地协作与只读查看 | 按需联网 |
|
||||
|
||||
## 安全约定
|
||||
|
||||
- Token 只在 `%USERPROFILE%\.git-skills\token.dpapi`,绑定当前 Windows 用户
|
||||
- Agent 不得读取该文件,不得让你在聊天里贴 Token
|
||||
- 不修改已有 `origin`,不改全局 `user.name` / `user.email`
|
||||
- 不 `--force`、不 `reset --hard`、不跳过 hooks,除非你写明要求
|
||||
|
||||
## Gitea 密钥:添加 → 验证(必做)
|
||||
|
||||
官方:[GPG/SSH Commit Signatures](https://docs.gitea.com/administration/signing/)。完整步骤见 [gitea.md](../.cursor/skills/git-init/gitea.md)。
|
||||
|
||||
网页灰色开锁 /「找不到此签名对应的密钥」= 库中没有**已验证**的可用密钥。只「增加密钥」不够,必须在 `https://<你的Gitea>/user/settings/keys` 点 **验证**。
|
||||
|
||||
### 验证 GPG(本 Skill 默认用 GPG 签提交)
|
||||
|
||||
在 Cursor 里说「验证 Gitea GPG/SSH 密钥」即可。Agent 会**主动问你要页面令牌**,然后生成签名块给你贴回。
|
||||
|
||||
也可本机自己跑:
|
||||
|
||||
```powershell
|
||||
$scripts = "$env:USERPROFILE\.cursor\skills\git-init\scripts"
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File "$scripts\verify-gitea-keys.ps1" `
|
||||
-GpgToken "GPG页面令牌" `
|
||||
-SshToken "SSH页面令牌" `
|
||||
-KeyId "你的GPG_Key_ID"
|
||||
```
|
||||
|
||||
(你当前本机 Key ID 示例:`5996DA789B43D451`,以 `gpg --list-secret-keys --keyid-format LONG` 或 Gitea 页面为准。)
|
||||
|
||||
说明:
|
||||
|
||||
- **可以**把「验证」页上的一次性挑战令牌发给 Agent(不是访问令牌)
|
||||
- **不要**把 HTTPS 访问令牌发到对话;访问令牌只用 `store-token.ps1`
|
||||
- Agent 生成签名后,把 `BEGIN PGP SIGNATURE` / `BEGIN SSH SIGNATURE` 贴回 Gitea → **验证**
|
||||
- 本地保持:
|
||||
|
||||
```powershell
|
||||
git config user.signingkey <你的GPG_Key_ID>
|
||||
git config commit.gpgsign true
|
||||
git config --unset gpg.format # 若曾设为 ssh
|
||||
```
|
||||
|
||||
官方:GPG 用 `echo "TOKEN"`(有换行);SSH 用 `echo -n`(无换行)。验证成功后**新提交**才会显示已验证;旧提交可能仍开锁。硬刷新(Ctrl+F5)再看。
|
||||
|
||||
## 本机依赖
|
||||
|
||||
- Git for Windows(含 Git Credential Manager、建议用自带 `gpg.exe` / Git Bash)
|
||||
- Windows OpenSSH(`ssh-keygen` / `ssh-agent`)
|
||||
- GPG(Gpg4win,或 Git 自带 `gpg`)
|
||||
|
||||
## 常见问题
|
||||
|
||||
**对话里提示 profile/token missing**
|
||||
本机跑 `store-profile.ps1` / `store-token.ps1`。
|
||||
|
||||
**HTTPS 推送失败**
|
||||
令牌是否过期、是否勾选仓库写权限;自建是否带端口(如 `:3000`);重新 `store-token` 后再推送。
|
||||
|
||||
**SSH Permission denied**
|
||||
公钥是否已加到 Gitea;自定义端口 URL 是否写成 `ssh://git@host:2222/...`。用 `test-ssh.ps1` 测。
|
||||
|
||||
**首次连接自建主机问 fingerprint**
|
||||
在本机终端确认 host key,不要把 Token 发到聊天。
|
||||
|
||||
**提交在 Gitea 网页显示「找不到此签名对应的密钥」**
|
||||
对 Cursor 说「验证 Gitea SSH 和 GPG」。Agent 会主动要两个页面挑战令牌并生成签名块。HTTPS 访问令牌仍不要发到对话。详见 [gitea.md](../.cursor/skills/git-init/gitea.md)。
|
||||
|
||||
**改了 Skill 但行为没变**
|
||||
再跑 `install.ps1`,必要时重开对话。
|
||||
+326
@@ -0,0 +1,326 @@
|
||||
# git-init 架构
|
||||
|
||||
本文说明组件如何分工、密钥放在哪、各条 Git 路径怎么走。使用步骤见 [使用文档.md](使用文档.md)。
|
||||
|
||||
## 设计目标
|
||||
|
||||
- **对话里只出现 Gitea 仓库 URL 和 SSH/GPG 选择**,不出现 Token
|
||||
- **同一套本机档案**服务于初始化以及之后每一次提交、推送、克隆、拉取
|
||||
- **默认远程为 Gitea**(自建域名与自定义端口);脚本按 URL 解析 host/port
|
||||
- **Windows PowerShell** 可执行;不用 `eval "$(ssh-agent -s)"`
|
||||
- **可复用**:源码在仓库 `.cursor/skills/git-init`,`install.ps1` 同步到个人 Skill 目录
|
||||
|
||||
## 逻辑架构
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
user[UserCursorChat]
|
||||
agent[AgentPlusSkill]
|
||||
scripts[PowerShellScripts]
|
||||
profile[ProfileJson]
|
||||
tokenFile[TokenDpapi]
|
||||
gcm[GitCredentialManager]
|
||||
sshAgent[WindowsSshAgent]
|
||||
gpg[GpgKeyring]
|
||||
git[GitRepo]
|
||||
remote[GiteaHost]
|
||||
|
||||
user --> agent
|
||||
agent --> scripts
|
||||
scripts --> profile
|
||||
scripts --> tokenFile
|
||||
tokenFile -->|"decrypt CurrentUser"| gcm
|
||||
scripts --> sshAgent
|
||||
scripts --> gpg
|
||||
agent --> git
|
||||
gcm --> remote
|
||||
sshAgent --> remote
|
||||
git --> remote
|
||||
```
|
||||
|
||||
三层:
|
||||
|
||||
1. **Skill 指令**(`SKILL.md`):路由到 Init / Commit / Push / Clone 等,并列出安全红线
|
||||
2. **脚本**(`scripts/`):状态检查、加密存取、注入凭据、SSH/GPG;stdout 不含 Token
|
||||
3. **本机秘密**(`%USERPROFILE%\.git-skills\`):与任何项目仓库隔离
|
||||
|
||||
## 目录与职责
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph repo [git-skillsRepo]
|
||||
skillMd[SKILL.md]
|
||||
workflows[workflows.md]
|
||||
reference[reference.md]
|
||||
examples[examples.md]
|
||||
scriptsDir[scripts]
|
||||
installPs[install.ps1]
|
||||
docsDir[docs]
|
||||
end
|
||||
|
||||
subgraph personal [UserHome]
|
||||
personalSkill[".cursor/skills/git-init"]
|
||||
secrets[".git-skills"]
|
||||
end
|
||||
|
||||
installPs -->|"copy skill not secrets"| personalSkill
|
||||
scriptsDir --> secrets
|
||||
```
|
||||
|
||||
| 路径 | 职责 |
|
||||
| --- | --- |
|
||||
| `.cursor/skills/git-init/SKILL.md` | Agent 入口:路由、红线、Init/Commit/Push |
|
||||
| `workflows.md` | Clone / Pull / Branch / Merge / Tag / Stash / Inspect |
|
||||
| `reference.md` | 中文提交规范、Windows SSH/GPG、故障表 |
|
||||
| `examples.md` | 触发例句 |
|
||||
| `scripts/*.ps1` | 可执行步骤;失败用退出码和 `key=value` |
|
||||
| `install.ps1` | 复制 Skill 到 `~/.cursor/skills/git-init` |
|
||||
| `%USERPROFILE%\.git-skills\profile.json` | 姓名、邮箱、HTTPS 用户名、SSH 路径 |
|
||||
| `%USERPROFILE%\.git-skills\token.dpapi` | 仅 Token,DPAPI `CurrentUser` |
|
||||
|
||||
Agent **可以**读 `profile.json`(经 `profile-status.ps1`)。Agent **不得**读 `token.dpapi`。
|
||||
|
||||
## 信任边界
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph chat [CursorChat]
|
||||
urlIn[RemoteUrl]
|
||||
talk[NoTokenInChat]
|
||||
end
|
||||
|
||||
subgraph machine [ThisWindowsUser]
|
||||
dpapi[DPAPI]
|
||||
gcm[GCM]
|
||||
sshKeys[SSHPrivateKey]
|
||||
gpgKeys[GPGSecretKey]
|
||||
end
|
||||
|
||||
subgraph project [GitWorkTree]
|
||||
gitDir[.git]
|
||||
ignore[.gitignore]
|
||||
end
|
||||
|
||||
subgraph host [Gitea]
|
||||
origin[origin]
|
||||
end
|
||||
|
||||
urlIn --> gitDir
|
||||
dpapi -->|"git credential approve stdin"| gcm
|
||||
gcm --> origin
|
||||
sshKeys --> origin
|
||||
gitDir --> origin
|
||||
ignore -->|"block secrets"| gitDir
|
||||
```
|
||||
|
||||
- 解密只在当前 Windows 用户下有效;换用户或换机器无法读 Token
|
||||
- 注入走 stdin 给 `git credential approve`,不写进命令行参数、不写进仓库
|
||||
- 项目 `.gitignore` 忽略 `.git-skills/`、`*.dpapi`、私钥
|
||||
|
||||
## 脚本调用关系
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
storeProfile[store-profile.ps1]
|
||||
storeToken[store-token.ps1]
|
||||
profileStatus[profile-status.ps1]
|
||||
tokenStatus[token-status.ps1]
|
||||
prepareCommit[prepare-commit.ps1]
|
||||
prepareAuth[prepare-auth.ps1]
|
||||
preparePush[prepare-push.ps1]
|
||||
inject[inject-credential.ps1]
|
||||
ensureSsh[ensure-ssh.ps1]
|
||||
ensureGpg[ensure-gpg.ps1]
|
||||
assertSecrets[assert-no-secrets.ps1]
|
||||
repoStatus[repo-status.ps1]
|
||||
common[common.ps1]
|
||||
|
||||
storeProfile --> common
|
||||
storeToken --> common
|
||||
profileStatus --> common
|
||||
tokenStatus --> common
|
||||
prepareCommit --> common
|
||||
prepareAuth --> inject
|
||||
prepareAuth --> ensureSsh
|
||||
preparePush --> prepareAuth
|
||||
inject --> common
|
||||
ensureSsh --> common
|
||||
ensureGpg --> common
|
||||
assertSecrets --> common
|
||||
repoStatus --> common
|
||||
```
|
||||
|
||||
| 脚本 | 谁跑 | 作用 |
|
||||
| --- | --- | --- |
|
||||
| `store-profile.ps1` / `store-token.ps1` | 用户本机终端 | 交互写入档案 / 加密 Token |
|
||||
| `profile-status.ps1` / `token-status.ps1` | Agent | `present` / `missing`,无密钥明文 |
|
||||
| `prepare-commit.ps1` | Agent | 本地作者 + `commit.gpgsign` |
|
||||
| `prepare-auth.ps1` | Agent | 按 URL 注入 GCM 或 ssh-add(克隆可用) |
|
||||
| `prepare-push.ps1` | Agent | 读 `origin` 再调 `prepare-auth` |
|
||||
| `ensure-ssh.ps1` / `ensure-gpg.ps1` | Agent | 复用或生成密钥;日常推送 `-NoGenerate -Quiet` |
|
||||
| `assert-no-secrets.ps1` | Agent | 提交前拦截密钥路径 |
|
||||
| `repo-status.ps1` | Agent | 分支、脏否、打码后的 origin |
|
||||
|
||||
## 主流程
|
||||
|
||||
### 总路由
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
start[UserRequest]
|
||||
start --> route{Intent}
|
||||
route -->|init| initPath[Init]
|
||||
route -->|commit| commitPath[Commit]
|
||||
route -->|push| pushPath[Push]
|
||||
route -->|commitAndPush| commitPath
|
||||
commitPath -->|ifAskedPush| pushPath
|
||||
route -->|clone| clonePath[Clone]
|
||||
route -->|pullOrFetch| syncPath[Sync]
|
||||
route -->|branchMergeTagStash| localPath[LocalGit]
|
||||
route -->|statusLogDiff| inspectPath[Inspect]
|
||||
route -->|commitButNotRepo| initPath
|
||||
```
|
||||
|
||||
### 初始化
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
detect[DetectRepoAndRemote]
|
||||
detect --> profile{ProfileAndToken}
|
||||
profile -->|missing| stopStore[StopTellUserRunStoreScripts]
|
||||
profile -->|ok| askUrl[NeedRemoteUrl]
|
||||
askUrl --> initGit[git init plus local author]
|
||||
initGit --> addOrigin[remote add origin]
|
||||
addOrigin --> inject[inject-credential]
|
||||
inject --> ssh[ensure-ssh plus ssh test]
|
||||
ssh --> gpg[ensure-gpg plus gpgsign]
|
||||
gpg --> hygiene[gitignore and README]
|
||||
hygiene --> firstCommit[Commit path]
|
||||
firstCommit --> firstPush[Push main]
|
||||
firstPush --> verify[status remote log signature]
|
||||
```
|
||||
|
||||
### 每次提交
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
prep[prepare-commit]
|
||||
prep --> signing{signing present}
|
||||
signing -->|missing| gpg[ensure-gpg]
|
||||
gpg --> prep
|
||||
signing -->|ok| inspect[status diff log]
|
||||
inspect --> secrets[assert-no-secrets]
|
||||
secrets -->|blocked| unstage[Unstage secret paths]
|
||||
secrets -->|ok| stage[Stage related files]
|
||||
stage --> msg[Chinese type colon description]
|
||||
msg --> commit[git commit -S]
|
||||
commit --> check[log show-signature]
|
||||
check --> maybePush{User asked push}
|
||||
maybePush -->|yes| pushPath[Push]
|
||||
maybePush -->|no| done[Stop]
|
||||
```
|
||||
|
||||
### 每次推送 / 克隆 / 拉取
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
needAuth[NeedNetworkAuth]
|
||||
needAuth --> hasRepo{Inside work tree}
|
||||
hasRepo -->|yes| prepPush[prepare-push]
|
||||
hasRepo -->|no clone| prepAuth[prepare-auth with URL]
|
||||
prepPush --> proto{Protocol}
|
||||
prepAuth --> proto
|
||||
proto -->|https| gcm[GCM uses injected token]
|
||||
proto -->|ssh| sshAdd[ssh-add Quiet]
|
||||
gcm --> gitNet[git push or clone or pull]
|
||||
sshAdd --> gitNet
|
||||
```
|
||||
|
||||
HTTPS:Token 解密后仅进入 `git credential approve` 的 stdin。SSH:用已有 `id_ed25519`,日常路径不生成新密钥、不打印公钥。
|
||||
|
||||
## Agent 控制流
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as User
|
||||
participant A as Agent
|
||||
participant S as Scripts
|
||||
participant G as Git
|
||||
participant H as GitHost
|
||||
|
||||
U->>A: 提交并推送
|
||||
A->>S: profile-status token-status repo-status
|
||||
S-->>A: present plus branch info
|
||||
A->>S: prepare-commit
|
||||
A->>S: assert-no-secrets
|
||||
A->>G: git commit -S
|
||||
A->>S: prepare-push
|
||||
S->>G: credential approve or ssh-add
|
||||
A->>G: git push
|
||||
G->>H: objects
|
||||
A-->>U: 作者签名与推送结果无 Token
|
||||
```
|
||||
|
||||
## 与原始任务的对应
|
||||
|
||||
[相关文档.md](../相关文档.md) 中的步骤映射:
|
||||
|
||||
| 文档章节 | 实现 |
|
||||
| --- | --- |
|
||||
| 一 init | `git init -b main` |
|
||||
| 二 用户信息 | `profile.json` + 仓库 local `user.name` / `user.email` |
|
||||
| 三 远程 | `git remote add origin`(已有则不改) |
|
||||
| 四 Token | DPAPI + GCM,禁止写入代码 |
|
||||
| 五 SSH | `ensure-ssh.ps1` + Windows `ssh-agent` |
|
||||
| 六 GPG | `ensure-gpg.ps1` + `commit.gpgsign` |
|
||||
| 七 / 十二 中文提交 | 每次 Commit 路径强制 `类型: 描述` |
|
||||
| 八 README | 缺失才生成 |
|
||||
| 九 / 十 首次提交推送 | Init 末尾走 Commit + Push |
|
||||
| 十一 验收 | `status` / `remote -v` / `log --show-signature` |
|
||||
|
||||
## Gitea URL 与凭据
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
url[GiteaRemoteUrl]
|
||||
url --> parse[Parse-GitRemoteUrl]
|
||||
parse --> httpsPath{Protocol}
|
||||
httpsPath -->|https or http| credHost[CredentialHost may include port]
|
||||
httpsPath -->|ssh| sshHost[Host plus optional Port]
|
||||
credHost --> inject[inject-credential to GCM]
|
||||
sshHost --> sshTest[test-ssh with ssh -p]
|
||||
inject --> pushHttps[git push HTTPS]
|
||||
sshTest --> pushSsh[git push SSH]
|
||||
```
|
||||
|
||||
| URL 示例 | CredentialHost | SSH 测试 |
|
||||
| --- | --- | --- |
|
||||
| `https://git.example.com/a/b.git` | `git.example.com` | 不适用 |
|
||||
| `https://git.example.com:3000/a/b.git` | `git.example.com:3000` | 不适用 |
|
||||
| `git@git.example.com:a/b.git` | 主机名(供日后 HTTPS) | `ssh -T git@...` |
|
||||
| `ssh://git@git.example.com:2222/a/b.git` | 主机名(不含 2222) | `ssh -p 2222 -T git@...` |
|
||||
|
||||
细节见 [gitea.md](../.cursor/skills/git-init/gitea.md)。
|
||||
|
||||
## Gitea 密钥验证(官方行为)
|
||||
|
||||
依据 [docs.gitea.com/administration/signing](https://docs.gitea.com/administration/signing/):灰色开锁 = 数据库中找不到可校验密钥。用户密钥须在 `/user/settings/keys` **验证**后,提交签名才能被识别。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
addKey[AddPubkeyOnGitea]
|
||||
addKey --> verifyClick[ClickVerifyOnSettings]
|
||||
verifyClick --> challenge[PageShowsToken]
|
||||
challenge --> localSign[verify-gitea-keys with tokens from chat]
|
||||
localSign --> paste[AgentShowsSignatureBlocks]
|
||||
paste --> verified[KeyMarkedVerified]
|
||||
verified --> newCommit[NewSignedCommitShowsVerified]
|
||||
```
|
||||
|
||||
| 脚本 | 对齐官方 UI |
|
||||
| --- | --- |
|
||||
| `verify-gitea-keys.ps1` | 编排:可缺令牌时提示 `need_token`;有令牌则调下面两个脚本 |
|
||||
| `verify-gpg-challenge.ps1` | `echo "TOKEN" \| gpg -a --default-key KEY --detach-sig`(有换行) |
|
||||
| `verify-ssh-challenge.ps1` | `echo -n 'TOKEN' \| ssh-keygen -Y sign -n gitea -f KEY`(无换行) |
|
||||
|
||||
HTTPS **访问令牌**禁止进对话。页面 **验证挑战令牌**可由 Agent 主动询问(一次性,不落盘)。
|
||||
Reference in New Issue
Block a user