`gh stack checkout` reports "Local stack matches remote" without comparing local branch refs
まだ誰も着手していません。
評価
調査の方向性
gh stack checkout コマンドから開始し、Local stack matches remote を報告するチェックを追跡します。git reset --hard でローカルブランチ ref を移動した後、提供された再現手順を実行します。完了の条件は、コマンドが記録された head または remote head と実際のローカル ref を比較し、差異がある場合に警告し、git branch -f による修正案を示すことです。
索引モデルが issue の本文から書いたものです。
説明
Summary
gh stack checkout reports ✓ Local stack matches remote when a local branch has diverged from its remote counterpart. It appears to compare its recorded state against the remote, and never against the actual local branch refs — so a local branch that has moved is invisible to the check.
$ git rev-parse --short=10 stack-b-two # local
df863cea57
$ git rev-parse --short=10 origin/stack-b-two # remote, one commit ahead
41fd74d3ae
$ gh stack checkout 6
✓ Local stack matches remote — switching to branch (stack #6)
ℹ Already on stack-b-two
$ gh stack view --short # no warning, no ⚠ Needs rebase
Stack #6
» stack-b-two ○ #5 (current)
├ stack-b-one ○ #4
└ main
The extension's own state file held the correct value the whole time:
$ jq -r '.stacks[].branches[] | select(.branch=="stack-b-two") | .head' .git/gh-stack
41fd74d3ae... # matches the remote; the local ref is what diverged
So this is not stale metadata. Recorded state and remote agreed, the local ref disagreed with both, and nothing compared against it.
Why this matters
This is the reassurance a user sees immediately before #380 destroys their work. In that state gh stack push rewinds the remote branch and the commits become unreachable — and if the branch loses its only commit, GitHub auto-closes the PR with no files. The sequence is:
gh stack checkout <n> -> "✓ Local stack matches remote"
gh stack push -> "✓ Pushed N branches" (remote commits gone, PR closed)
Fixing #380 addresses the destruction. Fixing this addresses the false confidence that leads someone to run the command in the first place.
How a local branch gets behind
Anything not mediated by the extension. A plain git fetch after a colleague pushes; CI committing to the PR head branch (the trigger in #380); or building a change in a git worktree and pushing it with git push origin <scratch-ref>:<pr-branch>, which moves the remote and leaves the local branch untouched.
Reproduction
Against a stack whose branches are in sync:
git switch <top-branch>
git reset --hard HEAD~1 # simulate the local branch falling behind
gh stack checkout <stack-number> # -> "✓ Local stack matches remote"
gh stack view --short # -> no warning
Public repo with two stacks set up for this: https://github.com/xn/gh-stack-repro
Expected
Compare recorded/remote heads against the actual local branch refs. On divergence, say so and name the fix (git branch -f <b> origin/<b>), rather than reporting a match.
A gh stack status / gh stack doctor surfacing per-branch local-vs-remote drift would cover the general case, since plain git will always be able to desync the extension's state.
Environment
gh2.97.0gh-stackv0.1.0- git 2.50.1
- macOS 26.4.1, darwin/arm64
Related
- #380 — the data loss this false reassurance leads into.
- #193 — handling rebases performed outside
gh stack; same general gap (external git operations invisible to the extension).
- 主要言語
- Go
- スター
- 1.5k
- フォーク
- 73
- 平均マージ
- 1日 8時間
- マージ済み PR(30日)
- 7
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
github/gh-stack のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
-
難易度 1/5 1時間未満 初心者へのやさしさ 92/100
-
feature request topic: cli - general
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
feature request topic: auto-merge
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
-
bug topic: docs
難易度 1/5 1時間未満 初心者へのやさしさ 68/100
github/gh-stack の issue をすべて見る
似ている issue
-
area/dev-productivity area/disaster-recovery area/ipcei kind/enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
kind/bug status/0-triage
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
🤔 refinement needed
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
equinor/radix-operator#1979 ·