Skip to content

ensure local trunk branch for required operations#127

Open
skarim wants to merge 2 commits into
skarim/init-rm-silent-add-prefixfrom
skarim/fix-missing-trunk-branch
Open

ensure local trunk branch for required operations#127
skarim wants to merge 2 commits into
skarim/init-rm-silent-add-prefixfrom
skarim/fix-missing-trunk-branch

Conversation

@skarim

@skarim skarim commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

When a user starts a stack after renaming their initial branch (e.g. git branch -m newbranch), the trunk branch (e.g. main) may not exist as a local branch. Commands that pass the trunk name to git operations like merge-base, rebase, or rev-parse then fail with:

✗ failed to check linearity for skarim/api-token-warning: failed to run git: fatal: Not a valid object name main

The fix adds an ensureLocalTrunk helper that checks whether trunk exists locally and, if not, fetches it from the remote and creates a local tracking branch. This mirrors the pattern already used in the checkout command for importing stacks.

Changes

cmd/utils.go:

  • ensureLocalTrunk: New helper — checks BranchExists(trunk), returns early if present. Otherwise calls FetchBranches(remote, [trunk]) then CreateBranch(trunk, remote+"/"+trunk). Logs a success message when creating.
  • fastForwardTrunk: Fix incorrect comment that claimed "the remote tracking ref is sufficient for rebasing" — verified empirically that git rebase main fails when main has no local branch, even after fetching origin/main.

cmd/modify.go:

  • In checkModifyPreconditions, resolve the remote and call ensureLocalTrunk before CheckStackLinearity. This is the originally reported failure — IsAncestor(trunk, branch) crashed without a local trunk.

cmd/rebase.go:

  • In runRebase, call ensureLocalTrunk after fetch and before fastForwardTrunk and the cascade rebase. git rebase requires a locally resolvable ref; the remote tracking ref alone is not sufficient.

cmd/trunk.go:

  • In runTrunk, call ensureLocalTrunk before CheckoutBranch so that gh stack trunk works even when trunk was never created locally. Only resolves the remote if trunk is actually missing.

cmd/checkout.go:

  • Refactor the existing inline BranchExists + CreateBranch block to use the shared ensureLocalTrunk helper (DRY).

Commands already safe (no changes needed)

Command Why
sync Fetches trunk explicitly; fastForwardTrunk guards with BranchExists
push, switch, navigate, unstack Do not reference trunk
add, submit Do not require trunk as a local git ref
view Handles IsAncestor errors gracefully (false positive is acceptable since rebase will fix it)

When a user starts a stack after renaming their initial branch
(e.g. `git branch -m newbranch`), the trunk branch (e.g. main) may
not exist as a local branch. Commands that pass the trunk name to git
operations like merge-base, rebase, or rev-parse then fail with:

  fatal: Not a valid object name main

Add an `ensureLocalTrunk` helper that checks whether the trunk branch
exists locally and, if not, fetches it from the remote and creates a
local tracking branch. This mirrors the pattern already used in the
checkout command for importing stacks.

Commands updated:
- modify: call ensureLocalTrunk before the linearity check in
  CheckStackLinearity, which uses IsAncestor(trunk, branch). This was
  the originally reported failure.
- rebase: call ensureLocalTrunk after fetch and before fastForwardTrunk
  and the cascade rebase. git rebase requires a locally resolvable ref;
  the remote tracking ref alone is not sufficient.
- trunk: call ensureLocalTrunk before CheckoutBranch so that
  `gh stack trunk` works even when trunk was never created locally.
- checkout: refactor the existing inline BranchExists + CreateBranch
  block to use the shared helper.

Also fix an incorrect comment in fastForwardTrunk that claimed "the
remote tracking ref is sufficient for rebasing" — verified empirically
that `git rebase main` fails when main has no local branch, even after
fetching origin/main.

Commands that were already safe and required no changes:
- sync: fetches trunk explicitly and fastForwardTrunk guards with
  BranchExists
- push, switch, navigate, unstack: do not reference trunk
- add, submit: do not require trunk as a local git ref
- view: handles IsAncestor errors gracefully (false positive is
  acceptable since rebase will fix it)
@skarim skarim marked this pull request as ready for review June 15, 2026 11:30
Copilot AI review requested due to automatic review settings June 15, 2026 11:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a class of errors that occur when users start a stack after renaming their initial branch (e.g., git branch -m newbranch), causing the trunk branch (like main) to not exist locally. Commands that reference trunk in git operations (merge-base, rebase, rev-parse) would fail. The fix introduces a shared ensureLocalTrunk helper that fetches and creates a local tracking branch when trunk is missing, then integrates it into all commands that need trunk to exist locally.

Changes:

  • New ensureLocalTrunk helper in cmd/utils.go that checks if trunk exists locally, and if not, fetches and creates it from the remote tracking branch.
  • Integrated the helper into modify, rebase, trunk, and checkout commands, with the checkout.go refactored to use the shared helper (DRY).
  • Updated the fastForwardTrunk comment to correctly reflect that callers should use ensureLocalTrunk beforehand.
Show a summary per file
File Description
cmd/utils.go Adds ensureLocalTrunk helper and updates fastForwardTrunk comment
cmd/utils_test.go Tests for the new helper covering all branches (exists, fetch+create, fetch fail, create fail)
cmd/modify.go Calls ensureLocalTrunk in checkModifyPreconditions before linearity check
cmd/rebase.go Calls ensureLocalTrunk after fetch and before cascade rebase
cmd/trunk.go Calls ensureLocalTrunk gated behind !BranchExists before checkout
cmd/trunk_test.go Integration test for trunk command when trunk is missing locally
cmd/checkout.go Refactors inline trunk creation to use the shared helper

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 7/7 changed files
  • Comments generated: 1

Comment thread cmd/modify.go
GitHub Advanced Security started work on behalf of skarim June 15, 2026 11:47 View session
GitHub Advanced Security finished work on behalf of skarim June 15, 2026 11:48

@ktravers ktravers left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I was going to ask about this in #125, since it seemed like a pre-req.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants