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 <branch> onto <base> 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
# 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
Bug
When a branch in the stack is checked out in another git worktree,
gh stack rebasereports the rebase as successful even thoughgit rebase --ontonever actually ran. The branch is left unchanged, but the tool prints✓ Rebased <branch> onto <base>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 togit rebase --onto.Reproduction
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:
Verified results
43ad749d18dc33✓ Rebasedecc824214b6318✓ Rebased924657b924657b✓ Rebased4c700aa4c700aa✓ RebasedbranchC and branchD do not contain the new trunk commit (
trunk-new.txt), confirming the rebase never happened. The exit code is 0 (success).Impact
git rebase --ontofails before starting (e.g. invalid refs) may exhibit the same silent-success behavior