Skip to content

[Feature] Support base ref when working with stacks #599

Open

Description

@tcooper-uk

Support rebasing stacks onto a base ref

Summary

gh stack rebase and gh stack sync always rebase the bottom of a stack onto the head of
the trunk branch (e.g. origin/main). I'd like to propose an opt-in --base-ref flag and a
matching gh-stack.base-ref git config key, so a stack can be rebased onto another ref such
as a moving stable tag while pull requests still target the trunk branch on GitHub.

Motivation

Many trunk-based teams keep a "known good" pointer behind the trunk head. Once a commit on
main has passed the full CI pipeline, a tag or branch (commonly stable, green or
last-good) is moved forward to that commit, and engineers start new work from that pointer
instead of from main. This is also common when creating a patch from a known release.

gh stack currently defeats this workflow. Every rebase / sync pulls the head of the
trunk into the bottom of the stack: the trunk is fetched and fast-forwarded, and the cascade
rebases onto it. There is no way to say "rebase from this tag instead". init has the same
limitation, since it creates the first branch from the trunk head.

Proposal

Separate two things that are currently both "trunk":

  1. The PR base on GitHub stays the trunk branch (main). A PR base must be a branch, and
    submit, push, link and merge are unaffected.
  2. The ref the stack is rebased onto locally becomes configurable.

Flag and config

  • --base-ref <ref> on gh stack init, gh stack rebase and gh stack sync.
  • git config gh-stack.base-ref <ref> as a repository-level default, following the existing
    gh-stack.remote / gh-stack.rerere-declined keys.
  • Precedence: flag, then git config, then current behaviour (trunk head).
  • Off by default. Behaviour is unchanged when neither is set.
  • --base-ref cannot be combined with rebase --no-trunk.

Accepted ref forms

  • A full ref (refs/tags/stable, refs/heads/stable) is used as given.
  • A remote-qualified branch (origin/stable) is accepted.
  • A bare name (stable) is looked up on the remote. If it exists as both a tag and a branch,
    the command fails and asks for the full ref.
  • Other namespaces and refs that exist only locally are errors.

Behaviour when a base ref is set

  • The ref is fetched explicitly.
  • The local trunk branch is not fast-forwarded. sync skips that step.
  • A rebase is needed when the first active branch's recorded base differs from the ref's
    SHA. This covers the ref moving forward, backwards or sideways.
  • Rolled-back refs. If the ref moves backwards to an ancestor of the stack, a plain
    git rebase <ref> treats the branch as up to date and silently keeps the commits between
    the two, so the bad commits would stay in the stack. Instead the bottom branch is rebased
    --onto <ref> <recorded base>, which replays only the branch's own commits. If there is no
    usable recorded base and the ref is inside the branch's history, the command fails with
    guidance rather than doing nothing.
  • The resolved SHA is pinned in the existing rebase journal, so --continue is unaffected if
    the ref moves again mid-rebase.
  • If a PR in the stack has merged into the trunk but its merge commit is not yet in the base
    ref, the rest of the stack is still rebased onto the base ref. The merged branch's commits
    are dropped as they are today, and the merged change arrives once the ref catches up.
  • If GitHub has retargeted the stack to a different base branch, the base ref is ignored with
    a warning.
  • init --base-ref creates the first branch from the ref and records its SHA as the stack's
    trunk head. Adopted branches get their base measured against the ref.

What does not change

add, push, submit, link, merge, navigation, and the stack file schema. The prototype
needs no schema change, so there is no compatibility concern with older versions reading the
stack file.

Example

git config gh-stack.base-ref refs/tags/stable

gh stack init my-feature        # first branch is created from the stable tag
# ... commit ...
gh stack add my-feature-2
gh stack sync                   # fetches the tag, rebases the stack onto it,
                                # leaves local main alone, pushes
gh stack submit                 # PRs still target main

One-off use without config:

gh stack rebase --base-ref refs/tags/stable

Activity

  1. tcooper-uk commented on Oct 27, 2026

    @tcooper-uk
    Author

    I am unable to open my pull request for contribution due to the repository settings: main...tcooper-uk:gh-stack:base-ref-support

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions