之前写过很多篇Git相关文章:
- Git使用笔记
- Git Tag
- Git Cherry Pick
- Git clone/pull/push需要输入密码解决方法
- GitHub使用技巧
- Git:进阶、衍生
gh
GitHub官方开源(GitHub,43.6K Star,8.2K Fork)的基于Go开发的CLI工具,将GitHub的核心功能带到终端,支持问题管理、拉取请求、版本发布等完整工作流程。官网,官方文档。
gh提供非常完整的GitHub命令行操作集合,涵盖仓库管理、问题追踪、拉取请求、Gist、扩展管理等多个方面。
| 类别 | 命令 | 功能描述 | 常用参数/示例 |
|---|---|---|---|
| 仓库管理 | gh repo | 仓库相关操作 | 查看、创建、克隆、fork仓库 |
gh repo view | 查看仓库信息 | gh repo view owner/repo | |
gh repo create | 创建新仓库 | gh repo create --public --clone | |
gh repo clone | 克隆仓库 | gh repo clone owner/repo | |
gh repo fork | Fork仓库 | gh repo fork owner/repo --clone | |
gh repo list | 列出用户仓库 | gh repo list --limit 50 | |
| 问题管理 | gh issue | 问题相关操作 | 创建、查看、列出、关闭问题 |
gh issue list | 列出问题 | gh issue list --label bug --state open | |
gh issue create | 创建问题 | gh issue create --title "Bug" --body "描述" | |
gh issue view | 查看问题详情 | gh issue view 123 | |
gh issue close | 关闭问题 | gh issue close 123 --comment "已修复" | |
gh issue reopen | 重新打开问题 | gh issue reopen 123 | |
| 拉取请求 | gh pr | 拉取请求操作 | 创建、查看、合并、检查PR |
gh pr create | 创建PR | gh pr create --title "功能" --body "描述" | |
gh pr list | 列出PR | gh pr list --state open --author @me | |
gh pr view | 查看PR详情 | gh pr view 456 --web | |
gh pr checkout | 检出PR分支 | gh pr checkout 456 | |
gh pr diff | 查看PR差异 | gh pr diff 456 | |
gh pr merge | 合并PR | gh pr merge 456 --squash | |
gh pr status | 查看PR状态 | gh pr status | |
gh pr checks | 查看PR检查 | gh pr checks 456 | |
gh pr review | 提交PR审查 | gh pr review 456 --approve | |
| Gist管理 | gh gist | Gist相关操作 | 创建、查看、编辑、删除Gist |
gh gist create | 创建Gist | gh gist create file.txt --public | |
gh gist list | 列出Gist | gh gist list --limit 20 | |
gh gist view | 查看Gist | gh gist view abc123 | |
gh gist edit | 编辑Gist | gh gist edit abc123 file.txt | |
gh gist delete | 删除Gist | gh gist delete abc123 | |
| 扩展管理 | gh extension | 扩展管理 | 安装、升级、移除扩展 |
gh extension install | 安装扩展 | gh extension install owner/gh-extension | |
gh extension list | 列出扩展 | gh extension list | |
gh extension upgrade | 升级扩展 | gh extension upgrade all | |
gh extension remove | 移除扩展 | gh extension remove extension-name | |
| 版本发布 | gh release | 版本发布 | 创建、查看、下载发布 |
gh release create | 创建发布 | gh release create v1.0.0 --notes "发布说明" | |
gh release list | 列出发布 | gh release list --limit 10 | |
gh release view | 查看发布 | gh release view v1.0.0 | |
gh release download | 下载发布 | gh release download v1.0.0 | |
gh release delete | 删除发布 | gh release delete v1.0.0 --yes | |
| 工作流管理 | gh workflow | GitHub Actions工作流 | 查看、运行工作流 |
gh workflow list | 列出工作流 | gh workflow list | |
gh workflow view | 查看工作流 | gh workflow view build.yml | |
gh workflow run | 运行工作流 | gh workflow run build.yml | |
gh workflow disable | 禁用工作流 | gh workflow disable build.yml | |
gh workflow enable | 启用工作流 | gh workflow enable build.yml | |
| 运行器管理 | gh run | 运行器相关 | 查看运行状态、日志 |
gh run list | 列出运行 | gh run list --workflow build.yml | |
gh run view | 查看运行详情 | gh run view 12345 | |
gh run watch | 监视运行状态 | gh run watch 12345 | |
gh run download | 下载运行产物 | gh run download 12345 | |
gh run rerun | 重新运行 | gh run rerun 12345 | |
| 认证管理 | gh auth | 认证相关 | 登录、登出、状态检查 |
gh auth login | 登录GitHub | gh auth login --with-token | |
gh auth logout | 登出 | gh auth logout | |
gh auth status | 查看认证状态 | gh auth status | |
gh auth refresh | 刷新令牌 | gh auth refresh | |
| 配置管理 | gh config | 配置管理 | 设置、获取配置 |
gh config set | 设置配置 | gh config set git_protocol ssh | |
gh config get | 获取配置 | gh config get editor | |
gh config list | 列出所有配置 | gh config list | |
| 别名管理 | gh alias | 命令别名 | 设置、查看、删除别名 |
gh alias set | 设置别名 | gh alias set bugs 'issue list --label bug' | |
gh alias list | 列出别名 | gh alias list | |
gh alias delete | 删除别名 | gh alias delete bugs | |
| API调用 | gh api | 直接调用GitHub API | 灵活调用REST API |
gh api | 调用API端点 | gh api /user | |
gh api graphql | 调用GraphQL API | gh api graphql -f query='{ viewer { login } }' | |
| 浏览器 | gh browse | 在浏览器中打开 | 打开仓库、PR、Issue等 |
gh browse | 打开当前仓库 | gh browse | |
gh browse --issues | 打开Issues页面 | gh browse --issues | |
gh browse --pr 456 | 打开特定PR | gh browse --pr 456 | |
gh browse --wiki | 打开Wiki页面 | gh browse --wiki | |
gh browse --settings | 打开设置页面 | gh browse --settings | |
| 代码片段 | gh codespace | Codespace管理 | 创建、列出、删除 |
gh codespace list | 列出Codespace | gh codespace list | |
gh codespace create | 创建Codespace | gh codespace create --repo owner/repo | |
gh codespace delete | 删除Codespace | gh codespace delete codespace-name | |
| 密钥管理 | gh secret | Secrets管理 | 设置、列出、删除秘密 |
gh secret set | 设置秘密 | gh secret set MY_TOKEN -b"token-value" | |
gh secret list | 列出秘密 | gh secret list | |
gh secret delete | 删除秘密 | gh secret delete MY_TOKEN | |
| 环境管理 | gh environment | 环境管理 | 查看、配置环境 |
gh environment list | 列出环境 | gh environment list | |
gh environment view | 查看环境详情 | gh environment view production | |
| 缓存管理 | gh cache | Actions缓存管理 | 查看、删除缓存 |
gh cache list | 列出缓存 | gh cache list | |
gh cache delete | 删除缓存 | gh cache delete cache-key | |
| 搜索功能 | gh search | 搜索GitHub内容 | 搜索仓库、代码、议题等 |
gh search repos | 搜索仓库 | gh search repos "react hooks" --language=JavaScript | |
gh search code | 搜索代码 | gh search code "useState" --repo=facebook/react | |
gh search issues | 搜索议题 | gh search issues "bug" --state=open | |
gh search prs | 搜索PR | gh search prs "feature" --author=octocat | |
| 项目板管理 | gh project | 项目管理 | 查看、创建项目 |
gh project list | 列出项目 | gh project list --owner org | |
gh project view | 查看项目 | gh project view 123 | |
gh project create | 创建项目 | gh project create --title "新项目" | |
| 团队管理 | gh team | 团队管理 | 查看、管理团队 |
gh team list | 列出团队 | gh team list --org github | |
gh team view | 查看团队 | gh team view engineering | |
| 通知管理 | gh notification | 通知管理 | 查看、管理通知 |
gh notification list | 列出通知 | gh notification list | |
gh notification view | 查看通知 | gh notification view 123 | |
gh notification mark | 标记通知 | gh notification mark --read 123 | |
| 赞助管理 | gh sponsor | 赞助管理 | 查看、管理赞助 |
gh sponsor list | 列出赞助者 | gh sponsor list | |
gh sponsor view | 查看赞助详情 | gh sponsor view octocat | |
| 帮助信息 | gh help | 帮助信息 | 查看命令帮助 |
gh help | 显示帮助概览 | gh help | |
gh help <command> | 查看命令帮助 | gh help pr | |
gh help --web | 在浏览器中打开帮助 | gh help pr --web | |
| 版本信息 | gh version | 版本信息 | 显示gh版本 |
gh version | 显示版本号 | gh version | |
gh upgrade | 升级gh | gh upgrade |
高级功能
- 脚本和自定义
- API调用:直接调用GitHub API进行自动化操作
- 自定义别名:为常用命令创建快捷方式
- 输出格式化:支持JSON、YAML等格式输出
- 企业支持
- GitHub Enterprise:连接到企业版GitHub
- 认证管理:支持多种认证方式
实战
提供多种安装方式:
- 官网或GitHub Release页面下载
- 命令行
brewinstallgh使用示例:
# 登录GitHub帐户进行身份验证gh auth login gh authlogoutgh auth refresh gh auth setup-git# 设置首选编辑器gh configseteditor<editor># 为常用命令设置别名ghaliassetghaliaslist ghaliasimportghaliasdelete gh issue list ghprcreate# 在Visual Studio Code中打开一个代码空间gh codespace code# 将SSH密钥添加到GitHub帐户gh ssh-keyaddgh gist clone gh gist create gh gist delete gh gist edit gh gist list gh gistrenamegh gist viewgh-aw
官网,GitHub官方开源(GitHub,4.2K Star,329 Fork)的一款基于gh的扩展,全称为gh-aw(GitHub CLI extension for AWS),核心是打通GitHub CLI与AWS的操作链路,让开发者可直接通过gh命令行一站式管理与GitHub集成的AWS资源,无需切换多个工具或终端会话。
核心特点
- 工具集成化:将GitHub CLI与AWS CLI能力融合,统一操作入口,减少跨工具切换成本;
- 场景聚焦:针对GitHub与AWS协同的核心场景(如AWS资源与GitHub仓库/Action联动、身份认证打通等)做轻量化适配;
- 命令轻量化:基于
gh扩展体系设计,命令语法贴合gh生态习惯,开发者无需重新学习全新命令逻辑; - 官方:由GitHub官方维护,兼容性和安全性有保障,适配GitHub生态的最新特性;
- 易安装扩展:遵循
gh extension标准安装方式(gh extension install github/gh-aw),秒级完成部署使用; - 云资源联动:简化GitHub Actions调用AWS资源、GitHub仓库关联AWS服务(如CodeBuild、ECR等)的配置与操作流程。
worktree
实现:同一个仓库,开多个工作目录,同时在不同分支干活,互不打扰。
优势:
- 完全隔离:每个目录之间文件互不干扰,告别冲突。
- 共享历史:所有worktree共享同一个Git历史,
commit、branch、remote完全同步。 - 告别
git stash:你的工作现场被原封不动地保留。 - 零上下文切换开销:AI 助手在每个环境中都保持完整的记忆。
- 从根源上杜绝提交错分支:你不可能在
ml-project-bugfix目录里把代码提交到feature分支。
共享仓库对象 + 独立工作区状态:
- 提交历史、对象库这些核心内容是共享的。
- 每个 worktree 有自己独立的
HEAD、index和工作目录状态。 - 所以你可以在 A 目录做 feature,在 B 目录修 hotfix,不用反复来回切分支。
流程示例:
gitworktreeadd-bemergency-fix../temp mastercd../temp# 修Bug然后提交gitcommit-a-m"emergency fix"cd-gitworktree remove../temp命令行:
add:创建新 worktreelist:查看所有 worktreeremove:删除 worktreemove:移动 worktree 目录lock/unlock:锁定或解锁(防止被误删或被 prune)prune:清理失效的 worktree 元数据repair:手动移动目录后修复链接关系
规则
- Git 默认不让同一个分支同时在多个 worktree 被 checkout:保护机制,不是限制你发挥。它是在防止你自己把分支状态写乱。
--force在某些场景下要用两次:如操作一个“已锁定”的 worktree,文档明确说可能需要--force --force。不是Bug,是有意提高危险操作门槛。
解决三个高频痛点:
- 任务切换成本:以前切任务是“清现场 + 切分支 + 祈祷不冲突”。现在是“切目录”。任务边界从逻辑层落到了物理层。
- 上下文隔离:不同 worktree 对应不同任务,目录就是上下文。你一进目录就知道自己在干什么,不容易串台。
- 自动化友好:当你用脚本或 AI agent 并行跑任务时,worktree 是天然隔离单元。每个Agent绑一个目录,冲突明显下降。
进阶
参数:如果你要写脚本解析 git worktree list,别拿默认输出硬切字符串。
官方给稳定机器可读格式:--porcelain,再配-z处理特殊字符路径。--worktree配置
默认情况下,多个worktree共享仓库配置。
但有些配置你不想共享,如某个目录专用sparse-checkout或行为开关。
文档建议开启extensions.worktreeConfig,用git config --worktree写入当前工作区配置。
一句话:共享该共享的,隔离该隔离的。
多checkout场景整体仍有实验性质,submodule支持也并不完整。能不用superproject多重checkout就别硬上,至少先在团队里做小范围验证。
适用场景:
- 安全的框架迁移(无痛重构)
# 从Spring Security迁移到Sa-Tokengitworktreeadd../SaToken-migration-bexperiment/SaToken-migration maincd../SaToken-migration问题
- 每个worktree都有一套 Python或Node.js依赖,太占硬盘空间。
解决方案:使用共享的虚拟环境或容器化技术。
# 方案一:共享 Conda 环境 (推荐)conda create-nml-sharedpython=3.10conda activate ml-shared pipinstall-rrequirements.txt# 在所有 worktree 中都激活这个共享环境cd../ml-project-training&&conda activate ml-sharedcd../ml-project-inference&&conda activate ml-shared# 方案二:Poetry/pnpm 等自带缓存共享的包管理器poetry config cache-dir /shared/poetry-cache poetryinstall# 会使用共享的依赖缓存# 方案三:Docker 与共享卷dockerrun-v$(pwd):/workspace-vml-packages:/opt/conda/lib/python3.10/site-packages python:3.10高级玩法:
# 使用 Git 内置的垃圾回收和去重功能gitrepack-ad# (高阶操作,慎用!) 在 worktree 间共享 node_modules# 只适用于那些只读的依赖ln-s../../myapp-main/node_modules ./node_modules# 使用 pnpm 这类天生支持依赖共享的包管理器pnpminstall# 自动共享依赖包- 不同的机器学习 worktree 之间数据和模型发生冲突。
训练分支污染了生产分支的数据。
解决方案: 使用隔离的数据路径和模型版本管理工具。
# 为每个 worktree 设置不同的环境变量exportDATA_PATH=/data/training-experimentsexportMODEL_PATH=/models/training-v1exportDATA_PATH=/data/inference-productionexportMODEL_PATH=/models/production-v2# 或者用 Docker 卷进行数据隔离dockerrun--nameml-training-env-vtraining-data:/data-vtraining-models:/models python:3.10dockerrun--nameml-inference-env-vinference-data:/data-vproduction-models:/models python:3.10# 使用 MLflow 等模型注册中心进行版本管理mlflow server --backend-store-uri sqlite:///training.db --default-artifact-root ./training-artifacts mlflow server --backend-store-uri sqlite:///production.db --default-artifact-root ./production-artifacts- 每个 worktree 的包版本不一致,导致环境混乱。
解决方案: 使用锁文件(lockfiles)和版本固定。
# 创建新 worktree 后,第一时间复制锁文件cprequirements.txt../myapp-feature/cppoetry.lock../myapp-feature/# 或者在安装时就固定版本pipinstall--save-exacttorch==2.0.0torchvision==0.15.0工作流自动化脚本
一键创建Worktree工作区
#!/bin/bash# 保存为: create-worktree.shif[$#-eq0];thenecho"用法:$0<分支名> [基于哪个分支]"exit1fiBRANCH_NAME=$1BASE_BRANCH=${2:-main}REPO_NAME=$(basename$(git rev-parse --show-toplevel))WORKTREE_PATH="../${REPO_NAME}-${BRANCH_NAME}"# 创建 worktreegitworktreeadd-b"$BRANCH_NAME""$WORKTREE_PATH""$BASE_BRANCH" # 进入目录并设置环境 (根据你的项目修改) cd "$WORKTREE_PATH" pip install -r requirements.txt # 或者 npm install # 创建一个任务描述文件,方便 AI 理解 echo"# 任务: $BRANCH_NAME## 描述:[在这里写下你的任务描述]## 需要修改的文件:-## 完成标准:-" > TASK.md # 用VS Code打开 code . echo "Worktree创建成功:$WORKTREE_PATH" echo "任务文件已创建: TASK.md" echo "可以开始召唤 AI 助手了!"自动化清理脚本
#!/bin/bash# 保存为: cleanup-worktrees.shecho"正在清理已合并的 worktree..."# 遍历所有 worktree,但不包括主目录gitworktree list|grep-v"$(gitrev-parse --show-toplevel)"|whileread worktree branch commit;do# 提取纯粹的分支名branch_name=$(echo$branch|sed's/\[//g'|sed's/\]//g')# 检查分支是否已经合并到 mainifgitbranch--mergedmain|grep-q"$branch_name";thenecho"正在移除已合并的 worktree:$worktree($branch_name)"gitworktree remove"$worktree"gitbranch-d"$branch_name"fidoneecho"清理完成!"https://github.com/evmts/tevm-monorepo仓库,.claude/commands目录还有更多高级玩法。
AI与worktree
允许并行运行多个AI会话,每个会话都有自己独立的上下文。再也不用切换上下文。
AI的上下文来源:
- 文件系统感知:当前打开的文件、项目结构、目录组织
- Git历史集成:最近的提交记录、分支关系、变更模式
- 依赖理解:包管理文件(如
requirements.txt)、导入关系、环境配置 - 对话记忆:你的指令、偏好和正在进行的讨论
- 代码模式识别:编码风格、架构决策、命名约定
应用场景其一模型对决:A/B测试不同AI的实现
gitworktreeadd../ml-claude-implementation-bexperiment/claude-automl maingitworktreeadd../ml-codex-implementation-bexperiment/codex-automl main# 决定采用哪个方案gitadd-A# 回到主项目cd../ml-projectgitmerge experiment/claude-automl# 清理战场gitworktree remove../ml-claude-implementationgitbranch-dexperiment/claude-automlSubmodule
在浏览GitHub源码仓库时,经常会看到如下链接符号
点击文件夹,跳转到另一个GitHub仓库。
分析:这是Git子模块(Submodule)的GitHub页面的可视化表现,不是普通文件夹。
子模块是Git的一种功能,允许将一个Git仓库嵌套在另一个Git仓库中;父仓库不包含子模块的实际代码,只存储子模块仓库的URL和特定提交的SHA值。
如果代码库有隐藏文件.gitmodules,就表明其含有字模块,内容示例:
[submodule "rapidjson"] path = rapidjson url = https://github.com/Tencent/rapidjson.git那SHA值呢?
git clone后,根据本地.git/modules/config文件
命令行使用
# 初始化子模块gitsubmodule init# 添加子模块,git submodule add <子模块URL> <子模块目录>。默认使用子模块仓库的名称作为路径gitsubmoduleadd<子模块URL><子模块目录># 执行git clone,并添加为子目录https://github.com/Tencent/weui# 执行git clone,并重命名文件夹https://github.com/Tencent/weui myui# 更新子模块gitsubmodule update# 递归更新子模块(及其子模块)gitsubmodule update--recursive--remote# 列出子模块gitsubmodule# 检查子模块状态gitsubmodule status# 移除子模块gitsubmodule deinit[<path>]gitrm[<path>]在一个不含有子模块的代码库里,执行git submodule init命令,看起来没有任何效果,既不会产生.gitmodules文件,也不会生成.git/modules/<folder>隐藏文件夹。
重命名效果图
并同步修改.gitmodules文件。
子模块嵌套效果图
更新子模块:当子模块的维护者提交更新后,使用子模块的项目必须手动更新才能包含最新提交。