`gh stack rebase` silently succeeds when `git rebase --onto` fails to start (in branch checked out in another worktree)
- 主要語言
- Go
- 星號
- 1.5k
- 分支
- 70
- 平均合併
- 1 天 8 小時
- 30 天內合併 PR
- 7
描述
## Bug
When a branch in the stack is checked out in another git worktree, `gh stack rebase` reports the rebase as successful even though `git rebase --onto` never actually ran. The branch is left unchanged, but the tool prints `✓ Rebased onto ` and continues to the next branch, leaving the stack in an inconsistent state.
This affects **any branch after the first** in the rebase range, because those use `git.RebaseOnto()` which passes the branch name as an argument to `git rebase --onto`.
## Reproduction
```bash
# Setup: create a repo with trunk and 4 stacked branches
git init && git commit --allow-empty -m "init"
echo "trunk" > file.txt && git add file.txt && git commit -m "trunk base"
git checkout -b branchA && echo "A" > a.txt && git add a.txt && git commit -m "A"
git checkout -b branchB && echo "B" > b.txt && git add b.txt && git commit -m "B"
git checkout -b branchC && echo "C" > c.txt && git add c.txt && git commit -m "C"
git checkout -b branchD && echo "D" > d.txt && git add d.txt && git commit -m "D"
# (set up remote, push all branches, create .git/gh-stack state file)
# Add a new commit to trunk so rebase has something to do
git checkout master
echo "new" > new.txt && git add new.txt && git commit -m "trunk update"
# Create a worktree that checks out branchC
git worktree add /tmp/wt-C branchC
# Record SHAs before rebase
git rev-parse branchA branchB branchC branchD
# Run rebase from branchA
git checkout branchA
gh stack rebase
```
### Expected
An error indicating that branchC is checked out in another worktree, or at minimum the rebase should stop and report the failure.
### Actual
All branches reported as successfully rebased:
```
✓ Rebased branchA onto master
✓ Rebased branchB onto branchA
✓ Rebased branchC onto branchB ← WRONG: silently skipped
✓ Rebased branchD onto branchC ← WRONG: silently skipped
```
### Verified results
| Branch | SHA before | SHA after | Actually rebased? | Reported |
|--------|-----------|----------|-------------------|----------|
| branchA | `43ad749` | `d18dc33` | Yes | `✓ Rebased` |
| branchB | `ecc8242` | `14b6318` | Yes | `✓ Rebased` |
| branchC | `924657b` | `924657b` | **No (unchanged)** | `✓ Rebased` |
| branchD | `4c700aa` | `4c700aa` | **No (unchanged)** | `✓ Rebased` |
branchC and branchD do not contain the new trunk commit (`trunk-new.txt`), confirming the rebase never happened. The exit code is 0 (success).
## Impact
- **Silent data corruption**: branch pointers are unchanged but reported as rebased
- **Stack inconsistency**: subsequent branches rebase onto an un-rebased parent, so the entire upstack from the worktree-checked-out branch is silently left behind
- **Not limited to worktrees**: any scenario where `git rebase --onto` fails before starting (e.g. invalid refs) may exhibit the same silent-success behavior
貢獻指南
研究方向
從 `gh stack rebase` 入口點以及用於第一個分支之後的分支的 `git.RebaseOnto()` 呼叫開始;追蹤命令失敗是如何傳回的,以及成功輸出是如何產生的。重現 issue 中的 worktree 設定,並新增或更新回歸涵蓋範圍,以便回報 rebase 失敗,且後續分支不會被標記為成功。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- git, go
- 領域
- cli
- Issue 類型
- 缺陷
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 活躍度
- 活躍
- 描述清晰度
- 基本清楚
- 新手友好度
- 65/100