名称: gt 描述: 此技能应用于使用 Graphite (gt) 管理堆栈式拉取请求。当用户提到 gt 命令、堆栈管理、PR 工作流程或处理依赖分支时使用。对于理解堆栈导航、分支关系和 Graphite 的思维模型至关重要。
Graphite
概述
Graphite (gt) 是一个 CLI 工具,用于管理堆栈式拉取请求——将大型功能分解为小的增量变更,这些变更相互构建。此技能提供了有效使用 gt 所需的思维模型、命令参考和工作流程模式。
关键:始终使用 --no-interactive
切勿在没有 --no-interactive 的情况下调用任何 gt 命令。 这是一个由每个 gt 命令继承的全局标志,而不是每个命令的选项。
没有 --no-interactive,gt 可能会打开提示、分页器或编辑器,在代理/CI 上下文中无限期挂起。--force 标志不会阻止提示——您必须单独使用 --no-interactive。
# 错误 - 可能等待用户输入而挂起
gt sync
gt submit --force
gt track --parent main
# 正确 - 始终传递 --no-interactive
gt sync --no-interactive
gt submit --no-interactive
gt track --parent main --no-interactive
gt restack --no-interactive
gt create my-branch -m "message" --no-interactive
--interactive 控制的内容(所有内容均通过 --no-interactive 禁用):
- 提示(同步、删除、提交等中的确认对话框)
- 分页器(日志中的输出分页)
- 编辑器(创建/修改中的提交消息编辑,提交中的 PR 元数据编辑)
- 交互式选择器(检出、移动、跟踪中的分支选择)
注意: gt modify --interactive-rebase 是一个独立的、不相关的标志,用于启动 Git 交互式变基。它与全局 --interactive 不同。
核心思维模型
堆栈是线性链
一个堆栈是一个分支序列,其中每个分支(除了主干)恰好有一个父分支:
有效堆栈(线性):
main → feature-a → feature-b → feature-c
无效(不是堆栈):
main → feature-a → feature-b
└─────→ feature-x
关键概念
- 父-子关系:每个由 gt 跟踪的分支(除了主干)恰好有一个父分支,它构建在其之上
- 自动重新堆叠:修改分支时,gt 自动重新定位所有上游分支以包含更改
- 定向导航:
- 下游/向下:朝主干方向(朝基础) -
gt down从 feature-b → feature-a → main - 上游/向上:远离主干方向(朝顶部) -
gt up从 feature-a → feature-b → feature-c
- 下游/向下:朝主干方向(朝基础) -
- 主干:主分支(通常是
main或master),所有堆栈构建在其上
堆栈可视化 - 关键思维模型
使用 Graphite 堆栈时,始终将主干可视化在底部:
顶部 ↑ feat-3 ← 上游(叶)
feat-2
feat-1
底部 ↓ main ← 下游(主干)
定向术语 - 必须理解
- 上游 / 向上 = 远离主干 = 朝顶部 = 朝叶
- 下游 / 向下 = 朝主干 = 朝底部 = 朝 main
详细示例
给定堆栈:main → feat-1 → feat-2 → feat-3
如果当前分支是 feat-1:
- 上游:
feat-2,feat-3(子分支,朝顶部) - 下游:
main(父分支,朝底部)
如果当前分支是 feat-3(在顶部):
- 上游:(无,已在顶部/叶)
- 下游:
feat-2,feat-1,main(祖先,朝底部)
为何此思维模型至关重要
🔴 命令依赖此可视化:
gt up/gt down导航堆栈land-stack在特定方向遍历分支- 堆栈遍历逻辑(父/子关系)
🔴 常见错误: 认为“上游”意味着“朝主干”
- 错误: 上游 = 朝 main ❌
- 正确: 上游 = 远离 main ✅
🔴 PR 合并顺序: 始终从下到上(main 先,然后每层向上)
元数据存储
所有 gt 元数据存储在共享的 .git 目录中(可在工作树间访问):
.git/.graphite_repo_config- 仓库级配置(主干分支).git/.graphite_cache_persist- 分支关系(父-子图).git/.graphite_pr_info- 缓存的 GitHub PR 信息
重要: 由于元数据在共享的 .git 目录中,因此所有工作树间共享。
基本命令
记住:所有 gt 命令必须包含 --no-interactive(见上文关键:始终使用 --no-interactive)。
常见工作流程命令
| 命令 | 别名 | 目的 |
|---|---|---|
gt create [name] |
gt c |
创建新分支堆叠在当前分支上,并提交暂存更改 |
gt modify |
gt m |
修改当前分支(修正提交)并自动重新堆叠子分支 |
gt submit |
gt s |
推送分支并创建/更新 PR |
gt submit --stack |
gt ss |
提交整个堆栈(上 + 下) |
gt sync |
- | 从远程同步并提示删除已合并分支 |
导航命令
| 命令 | 别名 | 目的 |
|---|---|---|
gt up [steps] |
gt u |
向上移动堆栈(远离主干) |
gt down [steps] |
gt d |
向下移动堆栈(朝主干) |
gt top |
gt t |
移动到堆栈顶部 |
gt bottom |
gt b |
移动到堆栈底部 |
gt checkout [branch] |
gt co |
交互式分支检出 |
堆栈管理
| 命令 | 目的 |
|---|---|
gt restack |
确保每个分支在 Git 历史中有其父分支 |
gt move |
将当前分支重新定位到不同的父分支上 |
gt fold |
将分支的更改折叠到父分支中 |
gt split |
将当前分支拆分为多个单提交分支 |
gt log |
可视化堆栈结构 |
分支信息与管理
| 命令 | 目的 |
|---|---|
gt branch info |
显示分支信息(父分支、子分支、提交 SHA) |
gt parent |
显示父分支名称 |
gt children |
显示子分支名称 |
gt track [branch] |
开始用 gt 跟踪分支(设置父分支) |
gt untrack [branch] |
停止用 gt 跟踪分支 |
gt delete [name] |
删除分支并更新元数据 |
gt rename [name] |
重命名分支并更新元数据 |
工作流程模式
模式 1:创建新堆栈
以多个可审查块构建功能:
# 1. 从主干开始
gt checkout main --no-interactive
git pull
# 2. 创建第一个分支
gt create phase-1 -m "添加 API 端点" --no-interactive
# ... 进行更改 ...
git add .
gt modify -m "添加 API 端点" --no-interactive
# 3. 在顶部创建第二个分支
gt create phase-2 -m "更新前端" --no-interactive
# ... 进行更改 ...
git add .
gt modify -m "更新前端" --no-interactive
# 4. 提交整个堆栈
gt submit --stack --no-interactive
# 结果:创建 2 个 PR
# PR #101: phase-1 (基础: main)
# PR #102: phase-2 (基础: phase-1)
模式 2:响应审查反馈
更新堆栈中间的分支:
# 导航到目标分支
gt down --no-interactive # 根据需要重复
# 进行更改
# ... 编辑文件 ...
git add .
# 修改(自动重新堆叠上游分支)
gt modify -m "处理审查反馈" --no-interactive
# 重新提交堆栈
gt submit --stack --no-interactive
模式 3:添加到现有堆栈
在中间插入新分支:
# 检出要插入的父分支
gt checkout phase-1 --no-interactive
# 用 --insert 创建新分支
gt create phase-1.5 --insert -m "添加验证" --no-interactive
# 提交新 PR
gt submit --no-interactive
模式 4:合并后同步
在 GitHub 上合并 PR 后清理:
# 运行同步(--no-interactive 自动确认分支删除)
gt sync --no-interactive
# 结果:
# - 合并分支在本地删除
# - 剩余分支重新定位到主干
# - GitHub 上 PR 基础更新
模式 5:拆分大更改
将大提交拆分为可审查的部分:
# 检出有大提交的分支
gt checkout large-feature --no-interactive
# 拆分为单提交分支
gt split --no-interactive
# 有意义地重命名分支
gt rename add-api-endpoints --no-interactive
gt up --no-interactive
gt rename add-frontend --no-interactive
gt up --no-interactive
gt rename add-tests --no-interactive
# 提交
gt submit --stack --no-interactive
常见错误避免
-
不要直接使用
git rebase:使用gt modify或gt restack- gt 在重新定位时需要更新元数据 -
不要用
git branch -d删除分支:使用gt delete- 需要更新元数据以重新设置子分支 -
不要假设
gt submit只影响当前分支:它提交下游(所有祖先)。使用gt submit --stack包括上游 -
不要忘记在合并后
gt sync:陈旧分支积累,元数据过时 -
⚠️ 切勿使用
gt log short查看分支状态:输出格式反直觉,会混淆代理。使用gt branch info、gt parent或gt children进行显式元数据访问
快速决策树
何时使用 gt 命令:
- 开始新工作 →
gt create(设置父关系) - 编辑当前分支 →
gt modify(自动重新堆叠子分支) - 导航堆栈 →
gt up/down/top/bottom(在链中移动) - 查看结构 →
gt log(查看可视化) - 获取父分支 →
gt branch info(解析“Parent:”行) - 获取分支关系 →
gt parent/gt children(快速访问) - 提交 PR →
gt submit --stack(创建/更新所有 PR) - 合并后 →
gt sync(清理 + 重新定位) - 重新组织 →
gt move(更改父分支) - 合并工作 →
gt fold(合并到父分支) - 拆分工作 →
gt split(拆分为分支)
资源
参考/
包含详细命令参考和全面思维模型文档:
gt-reference.md- 完整命令参考、元数据格式详情和高级模式
当用户需要有关特定 gt 命令、元数据结构或复杂工作流程场景的详细信息时,加载此参考。