在 GitHub 上使用堆叠的拉取请求时,您经常需要更改栈的结构 - 重新排序分支、合并它们或重命名它们。GitHub CLI 扩展 gh stack 提供了强大的工具来轻松处理这个问题。
问题#
使用堆叠 PR 开发功能时,您经常遇到以下情况:
- 需要将分支移动到栈中更高或更低的位置
- 想要合并两个分支
- 需要从栈中删除分支但保留 PR
- 想要在现有分支之间插入新分支
- 需要重命名分支以更好地反映其内容
与其手动执行复杂的 git rebase 和 force push 操作,gh stack 提供了专门的命令。
解决方案#
GitHub CLI 提供两种主要方法来重新构建栈:
1. 使用 gh stack modify(推荐)#
此命令打开一个交互式终端 UI,让您可以进行结构更改并一次性应用所有更改。
gh stack modifybashTUI 界面支持以下键绑定:
| 键 | 操作 | 描述 |
|---|---|---|
x | Drop | 从栈中删除分支及其提交 |
d | Fold down | 将分支吸收到下方的分支中(向主干方向) |
u | Fold up | 将分支吸收到上方的分支中(远离主干方向) |
i | Insert below | 在下方插入新的空分支(向主干方向) |
I | Insert above | 在上方插入新的空分支(远离主干方向) |
Shift+↓ | Move down | 在栈中向下移动分支(向主干方向) |
Shift+↑ | Move up | 在栈中向上移动分支(远离主干方向) |
r | Rename | 重命名分支(打开内联提示) |
z | Undo | 撤消上次暂存的操作 |
Ctrl+S | Apply | 应用所有更改 |
2. 使用 gh stack unstack + gh stack init#
更手动的方法,但对于复杂更改很灵活:
# 1. 删除当前栈
gh stack unstack
# 2. 手动进行结构更改
git branch -m api-routes api-endpoints
git branch -d feature-removed
# 3. 使用新结构重新创建栈
gh stack init db-migrations api-endpoints frontendbash重新构建工作流程#
以下是重新构建栈的工作流程:
flowchart TD
A[当前栈] --> B{方法?}
B -->|交互式| C[gh stack modify]
B -->|手动| D[gh stack unstack]
C --> E[打开 TUI]
E --> F[选择操作]
F --> G[暂存更改]
G --> H{完成?}
H -->|否| F
H -->|是| I[Ctrl+S 应用]
D --> J[手动更改]
J --> K[git branch -m/-d]
K --> L[gh stack init]
I --> M[级联 rebase]
L --> M
M --> N[gh stack push]
N --> O[重新构建的栈]
实际示例#
示例 1:将分支向上移动#
假设您有一个从下到上的栈:
graph TD
A[main] --> B[db-migrations]
B --> C[api-routes]
C --> D[frontend]
D --> E[testing]
您想将 testing 移动到 api-routes 上方:
gh stack modify
# 使用 Shift+↑ 将 testing 向上移动
# Ctrl+S 应用bash结果:
graph TD
A[main] --> B[db-migrations]
B --> C[testing]
C --> D[api-routes]
D --> E[frontend]
示例 2:合并两个分支#
当您意识到两个分支应该合并时:
graph TD
A[main] --> B[db-migrations]
B --> C[api-routes]
C --> D[api-validation]
D --> E[frontend]
将 api-validation 折叠到 api-routes 中:
gh stack modify
# 选择 api-validation,按 d(fold down)
# Ctrl+S 应用bash结果:
graph TD
A[main] --> B[db-migrations]
B --> C[api-routes + validation]
C --> D[frontend]
示例 3:插入新分支#
当您需要在现有分支之间添加层时:
graph TD
A[main] --> B[db-migrations]
B --> C[api-routes]
C --> D[frontend]
在 api-routes 和 frontend 之间插入 auth-middleware:
gh stack modify
# 将光标放在 api-routes 上
# 按 I(insert above)
# 为新分支命名
# Ctrl+S 应用bash结果:
graph TD
A[main] --> B[db-migrations]
B --> C[api-routes]
C --> D[auth-middleware]
D --> E[frontend]
级联 Rebase 过程#
当您使用 gh stack modify 应用更改时,会发生以下过程:
sequenceDiagram
participant User as 您
participant CLI as gh stack modify
participant Git as Git
participant Remote as GitHub Remote
User->>CLI: gh stack modify
User->>CLI: 暂存更改(移动/折叠/插入)
User->>CLI: Ctrl-S 应用
CLI->>Git: 如需要重命名分支
CLI->>Git: 如需要插入新分支
CLI->>Git: 级联 rebase
loop 对于每个分支
CLI->>Git: 将当前分支 rebase 到下方分支上
Git-->>CLI: Rebase 完成
end
CLI->>User: 成功通知
User->>CLI: gh stack push
CLI->>Remote: 使用 `\-\-force-with-lease` 进行 force push
Remote-->>CLI: Push 成功
CLI-->>User: GitHub 上的栈已更新
重要注意事项#
[!WARNING]
- 无法修改已合并 PR 的分支
- 结构更改(drop、fold、insert、rename)不能在同一会话中混合
- 始终使用
--force-with-lease进行gh stack push以确保安全- 在大规模重新构建之前备份重要分支
最佳实践#
- 检查当前栈:在进行更改之前始终运行
gh stack view - 使用 TUI:
gh stack modify更安全,因为它在应用之前预览更改 - 本地测试:确保在推送之前 rebase 成功
- 沟通:通知您的团队关于主要栈结构更改
- 备份:为重要栈标记或分支备份