Functional Difference Between --downstack and --upstack in gh-stack rebase

The --downstack flag rebases from the trunk up to and including your current branch, while --upstack rebases from your current branch up to the top of the stack, allowing you to limit cascade-rebase operations to specific portions of your branch stack.

The gh-stack extension for GitHub CLI provides powerful stack-based workflows for managing dependent pull requests. When reorganizing your stack with gh stack rebase, understanding the functional difference between --downstack and --upstack lets you control exactly which branches get rebased without affecting the entire stack.

What --downstack and --upstack Do

Rebasing with --downstack

When you execute gh stack rebase --downstack, the command rebases all branches from the trunk (the first branch in the stack) up to and including your current branch. According to the source code in cmd/rebase.go at lines 70-78, this implementation keeps startIdx fixed at 0 (the trunk position) while setting endIdx to currentIdx + 1.

Rebasing with --upstack

Conversely, gh stack rebase --upstack rebases your current branch and every branch above it to the top of the stack. In cmd/rebase.go (lines 70-78), this sets startIdx to currentIdx while keeping endIdx at the full length of the stack slice.

Default Full-Stack Behavior

If you supply neither directional flag, gh stack rebase processes the entire stack from trunk to top, using the full range of stack indices.

Implementation Details in cmd/rebase.go

The core index manipulation logic resides in cmd/rebase.go between lines 70-78. The implementation evaluates which directional flag is present and adjusts the slice boundaries accordingly:

  • With --downstack: startIdx remains 0, endIdx becomes currentIdx + 1
  • With --upstack: startIdx becomes currentIdx, endIdx remains len(stack)

These flags are mutually exclusive; the command rejects simultaneous use of both options since they specify conflicting range constraints.

Integration with --no-trunk

The directional flags respect the --no-trunk option (lines 77-80 in cmd/rebase.go). When combining --upstack with --no-trunk, the rebase starts from your current branch but skips rebasing onto the trunk itself, effectively shifting the start index forward by one position.

Practical Usage Examples

The help text defined in cmd/rebase.go (lines 64-68) provides these concrete examples:


# Rebase the entire stack (default behavior)

gh stack rebase

# Rebase only the "down-stack": trunk → ... → current-branch

gh stack rebase --downstack

# Rebase only the "up-stack": current-branch → ... → top-of-stack

gh stack rebase --upstack

# Combine with --no-trunk to avoid rebasing onto the trunk branch

gh stack rebase --upstack --no-trunk

Test cases in cmd/rebase_test.go verify that --downstack limits rebasing to branches up to the current branch and that --upstack correctly limits operations to branches from the current branch upward.

Summary

  • --downstack limits rebasing to the trunk through your current branch by setting the end index to currentIdx + 1 while keeping the start at 0 in cmd/rebase.go.
  • --upstack limits rebasing to your current branch through the top of the stack by setting the start index to currentIdx while keeping the end at the stack length.
  • Both flags override the default full-stack behavior and are mutually exclusive.
  • When combined with --no-trunk, the start index shifts forward to skip the trunk branch (lines 77-80).

Frequently Asked Questions

What happens if I use both --downstack and --upstack together?

The flags are mutually exclusive, and gh stack rebase will reject this combination. The command logic in cmd/rebase.go treats these as conflicting options since they specify opposite directional constraints on the rebase range.

How does --no-trunk interact with these directional flags?

When --no-trunk is combined with --upstack or --downstack, the rebase range respects the directional limit but skips rebasing onto the trunk itself. This shifts the effective start index forward by one position, as implemented in lines 77-80 of cmd/rebase.go.

Where is the stack index logic defined?

The stack indexing utilities, including the IndexOf method used to determine currentIdx, are defined in internal/stack/stack.go. The rebase command imports these utilities to calculate slice boundaries in cmd/rebase.go.

Can I use these flags with other gh stack commands?

The --downstack and --upstack flags are specific to the rebase subcommand. They appear only in cmd/rebase.go and cmd/rebase_test.go, limiting their scope to cascade-rebase operations within the gh-stack workflow.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →