项目
项目 checkout 自动化应该显式且安全。公开的工作站仓库可以描述通用结构,但不应暴露私有工作。
标准布局
本地 checkout 使用 ghq 的目录模型:
~/repos/github.com/YunYouJun/workstation每台机器只需配置一次 ghq:
git config --global ghq.root ~/repos确认当前配置:
git config --global --get ghq.root尽可能通过 ghq clone 仓库:
ghq get git@github.com:YunYouJun/workstation.git
cd "$(ghq list -p github.com/YunYouJun/workstation)"这样本地路径会接近远程 URL,也避免 ~/repos/gh/yyj 这类私有简称。
活跃 GitHub 仓库
使用 CLI 拉取并 clone YunYouJun 最近 push 过的仓库:
workstation projects clone-active该命令默认是 dry-run。确认目标路径后,显式加 --yes 才会写入本机:
workstation projects clone-active --yes配置最近活跃仓库数量:
workstation projects clone-active --limit 20更短的写法:
wst p active --limit 20交互式选择要预览或 clone 的仓库:
wst p active --limit 50 -i也可以设置脚本默认值,适合写到 shell profile 或机器私有配置里:
WORKSTATION_ACTIVE_PROJECT_LIMIT=20 pnpm projects:clone-active配置项目根目录:
workstation projects clone-active --root ~/repos更新已存在的 checkout:
workstation projects clone-active --update --yes使用 HTTPS clone URL:
workstation projects clone-active --https --yes包含 forks 和 archived 仓库:
workstation projects clone-active --include-forks --include-archived如果想用脚本入口:
pnpm projects:clone-active实现上使用 gh api graphql,按 PUSHED_AT DESC 排序,比按字母或创建时间更接近“最近活跃”。先在本机完成 GitHub CLI 认证:
gh auth login当已安装 ghq,且主 ghq.root 与 --root 一致时,命令会使用 ghq get。否则回退到显式 git clone 路径:
~/repos/github.com/<owner>/<repo>本地状态巡检
换机或清理旧机器前,检查 ~/repos 下本地 Git 仓库是否还有需要处理的内容:
workstation projects status短命令和脚本入口:
wst p status
pnpm projects:status默认只显示需要关注的仓库,包括未提交文件、已提交但未 push、stash、没有 upstream 或 upstream 已消失的分支。显示所有仓库:
workstation projects status --all默认最多向下扫描 6 层目录。仓库目录嵌套更深时可以调大,想限制扫描范围时也可以调小:
workstation projects status --max-depth 8用于脚本或离机检查时,如果发现需要关注的仓库就返回非零退出码:
workstation projects status --check清单模式
清单模式可以 clone 任意 Git 源的常用项目,包括 GitHub、GitHub Enterprise、GitLab、git.example.com 等内部源。命令同样默认 dry-run,确认后再加 --yes:
wst p manifest --file projects.local.yaml
wst p manifest --file projects.local.yaml --yes也可以把常用项目清单放在私有配置仓库里,让 workstation 先读取配置仓库中的 projects.yaml:
wst p manifest https://git.example.com/<user>/<config-repo>
wst p manifest https://git.example.com/<user>/<config-repo> --group common --yes如果清单不在仓库根目录的 projects.yaml 或 projects.yml,指定内部路径:
wst p manifest --repo https://git.example.com/<user>/<config-repo> --manifest workstation/projects.yaml私有配置仓库会缓存到 ~/.cache/workstation/project-manifests/。项目本身仍会 clone 到 ~/repos/<host>/<repo-path> 这种接近 ghq 的路径;group 只用于筛选和组织清单,不进入目标路径。当主 ghq.root 与目标 root 一致,且目标路径与 clone URL 推导出的路径一致时使用 ghq get,否则回退到显式 git clone。
公开仓库只提交一个示例清单:
projects.example.yaml私有或机器特定项目放在:
projects.local.yamlprojects.local.yaml 会被 Git 忽略。
清单格式:
groups:
common:
root: ~/repos
host: git.example.com
repositories:
- name: github.com/YunYouJun/workstation
url: git@github.com:YunYouJun/workstation.git
- example/private-service
- name: local-alias/private-service
path: example/private-service如果只写 name: git.example.com/<group>/<repo>,CLI 会默认推断 SSH clone URL;加 --https 时会推断 HTTPS clone URL。也可以在 manifest 或 group 上配置 host,随后用 example/private-service 这类短路径。需要同时支持两种协议时,也可以写 sshUrl 与 httpsUrl,命令会按 --https 选择。
当本地目标路径需要和远端路径不同,使用对象格式的 name + path:name 是本地路径,path 是远端仓库路径。这种情况会自动避开 ghq get,用显式 git clone <url> <target>,避免 ghq 按远端 URL 放到另一个目录。
Git 多账号与来源隔离
同一台机器访问 GitHub、GitHub Enterprise、公司 GitLab 或其他内部 Git 源时,把“提交身份”和“远端认证账号”分开配置:
- 提交身份用 Git 的
includeIf按 checkout 目录选择。 - 认证账号用 SSH
Host/IdentityFile或 HTTPS credential helper 选择。 - 全局开启
user.useConfigOnly,避免 Git 自动猜测错误邮箱。 - 同一个 host 上有多个账号时,使用 SSH Host alias,并把仓库 remote 指向 alias。
全局 Git 配置只负责路由,不直接写默认身份:
[user]
useConfigOnly = true
[includeIf "gitdir:~/repos/github.com/"]
path = ~/.gitconfig-github
[includeIf "gitdir:~/repos/git.example.com/"]
path = ~/.gitconfig-work不同来源的身份放在独立文件里:
# ~/.gitconfig-github
[user]
name = Your Name
email = you@example.com# ~/.gitconfig-work
[user]
name = Your Name
email = you@company.exampleSSH 认证账号通过 host 配置决定:
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
IdentitiesOnly yes
Host git.example.com-work
HostName git.example.com
User git
IdentityFile ~/.ssh/id_ed25519_work
IdentitiesOnly yes同一 host 多账号时,仓库 remote 使用 alias:
git remote set-url origin git@git.example.com-work:team/repo.git检查当前仓库最终生效的身份与认证入口:
git config --show-origin --get user.name
git config --show-origin --get user.email
git remote -v
ssh -G git.example.com-work | grep identityfile不建议默认依赖 includeIf "hasconfig:remote.*.url:..." 根据 remote URL 自动切换身份。新 clone、fork + upstream、多 remote 仓库都可能让规则变得含糊;按 ~/repos/<host>/... 目录切换身份更容易预测和审计。
CLI 中对应的初始化任务是 git.include-if。先查看任务和预览写入内容:
wst init --list
wst init git.include-if --git-profile 'id=github;host=github.com;name=Your Name;email=you@example.com'确认后再应用:
wst init git.include-if --git-profile 'id=github;host=github.com;name=Your Name;email=you@example.com' --yes如果本机已经有 ~/.gitconfig-github 且其中包含 user.name / user.email,也可以直接让 CLI 推断默认 GitHub profile:
wst init git.include-if --yes需要手动选择初始化任务和输入身份信息时,使用交互模式:
wst init -i最佳实践
- 普通项目 checkout 优先使用
ghq。 - Git 提交身份按
~/repos/<host>/...目录切换,远端认证账号按 SSH host 或 credential helper 切换。 - 开启
user.useConfigOnly,让未匹配身份的仓库无法提交。 - 按用途分组项目,而不是按历史偶然性分组;分组不应改变 clone 目标路径。
- 公开示例保持通用。
- 对需要主动 push 的仓库优先使用 SSH URL。
- Clone 脚本默认使用 dry-run。
- 仓库已存在时跳过,除非显式请求更新模式。
- 目标目录应可配置,默认根目录为
~/repos。 - GitHub 特定的列表和认证流程使用
gh。 - “活跃仓库”发现使用
PUSHED_AT排序。
清单模式可以继续扩展更多分组,同时不需要把私有仓库名放进公开 Git。对于普通 Git 仓库,它会生成与 ghq 一致的目标路径。
迁移旧路径
如果此仓库已经存在于旧的简称路径,可以移动一次,并只在旧编辑器窗口或脚本还引用旧路径时保留兼容 symlink:
mkdir -p ~/repos/github.com/YunYouJun
mv ~/repos/gh/yyj/workstation ~/repos/github.com/YunYouJun/workstation
mkdir -p ~/repos/gh/yyj
ln -s ~/repos/github.com/YunYouJun/workstation ~/repos/gh/yyj/workstation当 shell 历史、编辑器工作区和本地脚本都使用新路径后,就可以移除兼容 symlink。