You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Stop sync/rebase reporting success on a stale trunk
`gh stack sync` and `gh stack rebase` could print a full success report
while leaving the stack based on the trunk it was created from. Two
independent causes.
1. A rebase git refused was reported as a success.
`tryAutoResolveRebase` returned nil whenever no rebase was in progress.
That is only a valid success signal after an auto-`--continue`; on the
first check it means `git rebase` exited non-zero without ever starting.
Every rebase funnels through it, so the cascade printed `✓ Rebased X onto
Y` for a rebase that never ran — a dirty tree, a branch checked out in
another worktree, an unresolvable upstream, or stale rebase state.
A rebase that never started is now a typed `*git.RebaseStartError`, which
the cascade and `modify` treat as fatal rather than as a conflict, so no
bogus recovery state is written and git's own message is surfaced.
2. The trunk ref was never verified against the remote.
`fastForwardTrunk` only warned when it could not move the local trunk
(checked out in another worktree, diverged, remote ref gone), and the
cascade then rebased onto the stale local trunk. Every freshness check
compared branches to the *local* trunk, so they all passed: `rebase`
claimed "rebased locally with main" and `sync` concluded nothing was
stale, force-pushed anyway, and said "Branches synced".
`resolveTrunkTarget` now resolves the ref the cascade must target. When
the local trunk cannot be updated it returns `<remote>/<trunk>` and says
why, so the stack ends up current regardless of why the local ref is
stuck. When the trunk no longer exists on the remote it fails with an
actionable message instead of silently rebasing onto a stale trunk. The
post-cascade check measures against that ref, and `sync` runs it before
pushing so an unrebased stack is never force-pushed.
Also fixed along the way:
- A remote-qualified trunk (`gh stack init --base origin/main`) is
normalized instead of being re-qualified into `origin/origin/main`,
in both commands and before fetch refspecs are built.
- `git rebase <option> --continue` is a usage error (exit 129), so
`--preserve-dates` broke every `--continue`. git persists the option
in the rebase state, so `--continue` alone honors it.
- `FetchBranches` reports real failures instead of `sync` printing
"Fetched latest changes" regardless.
- Preflight checks for a rebase in progress and a dirty tree, with
`--autostash` to opt out. Untracked files are not treated as dirty:
git rebases fine with them present. `--autostash` stashes once around
the whole cascade — git's own `--autostash` pops after every
individual rebase, landing the changes on the wrong branch.
- Both summaries now name the trunk ref and SHA the stack landed on.
Fixes#155, #176. Addresses discussion #215.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f5959297-80fd-4732-aeae-aa9a4b6a7755
cmd.Flags().StringVar(&opts.remote, "remote", "", "Remote to fetch from (defaults to auto-detected remote)")
89
108
cmd.Flags().BoolVar(&opts.committerDateIsAuthorDate, "committer-date-is-author-date", false, "Set the committer date to the author date during rebase")
90
109
cmd.Flags().BoolVar(&opts.committerDateIsAuthorDate, "preserve-dates", false, "Alias for --committer-date-is-author-date")
110
+
cmd.Flags().BoolVar(&opts.autostash, "autostash", false, "Stash uncommitted changes before rebasing and restore them afterwards")
0 commit comments