Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
419 changes: 112 additions & 307 deletions README.md

Large diffs are not rendered by default.

61 changes: 61 additions & 0 deletions docs/annotate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# gh-stack annotate

Add a markdown table to each PR description showing the full stack.

## Usage

```bash
gh-stack annotate 'STACK-ID'
gh-stack annotate 'STACK-ID' --badges # shields.io badges (public repos)
gh-stack annotate 'STACK-ID' --ci # skip confirmation prompt
gh-stack annotate 'STACK-ID' --prefix '#' # remove prefix from titles
gh-stack annotate 'STACK-ID' -p file.md # prepend file contents
```

## Output

Each PR in the stack gets a table added to its description:

```markdown
### Stack: STACK-ID

| PR | Title | Base |
|:--:|:------|:----:|
| #103 | [STACK-ID] Add validation | #102 |
| #102 | [STACK-ID] Implement feature | #101 |
| #101 | [STACK-ID] Initial scaffolding | main |
```

GitHub auto-links PR numbers. Hovering shows PR status.

## Flags

| Flag | Description |
|------|-------------|
| `--badges` | Use shields.io status badges (public repos only) |
| `--ci` | Skip confirmation prompt |
| `--prefix` | Characters to strip from PR titles in the table |
| `-p`, `--prelude` | File to prepend before the table |
| `-r`, `--repository` | Override repository (owner/repo) |
| `-o`, `--origin` | Git remote name (default: origin) |
| `-e`, `--excl` | Exclude PR by number (repeatable) |

## How it works

1. Finds all PRs with the identifier in their title
2. Builds a dependency graph from PR base branches
3. Generates a markdown table
4. Updates each PR description (idempotent)

The annotation is idempotent - running it multiple times updates the existing table rather than adding duplicates.

## When to use

- After creating all PRs in a stack
- After adding or removing PRs from a stack
- After PR status changes (to update badges)

## See also

- [log](log.md) - Visualize the stack
- [land](land.md) - Merge the stack
71 changes: 71 additions & 0 deletions docs/autorebase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# gh-stack autorebase

Rebuild and push an entire stack after local changes.

## Usage

```bash
gh-stack autorebase 'STACK-ID' -C /path/to/repo
gh-stack autorebase 'STACK-ID' -C /path/to/repo --ci # skip confirmation
gh-stack autorebase 'STACK-ID' -C /path/to/repo -b <sha> # cherry-pick boundary
```

## How it works

1. Checks out the base branch (e.g., `main`)
2. Cherry-picks commits from each PR in stack order
3. Updates local branches to point at new commits
4. Force-pushes all branches at once

This reconstructs a clean, linear stack from your local changes.

## Flags

| Flag | Description |
|------|-------------|
| `-C`, `--project` | Path to local repository (required) |
| `--ci` | Skip confirmation prompt |
| `-b`, `--initial-cherry-pick-boundary` | Stop initial cherry-pick at this SHA |
| `-o`, `--origin` | Git remote name (default: origin) |
| `-r`, `--repository` | Override repository (owner/repo) |
| `-e`, `--excl` | Exclude PR by number (repeatable) |

## Conflict handling

If a conflict occurs during cherry-picking:

1. The process pauses
2. Resolve conflicts manually
3. Stage resolved files with `git add`
4. Continue with `git cherry-pick --continue`

## Example

After amending a commit in the middle of your stack:

```bash
# Your local history diverged from remote
git checkout feat/part-1
git commit --amend -m "Updated message"

# Rebuild and sync the entire stack
gh-stack autorebase 'STACK-ID' -C .
```

## Warnings

- **Force-pushes** to all branches in the stack
- Back up your work before running
- Collaborators will need to reset their local branches

## When to use

- After amending commits
- After interactive rebase
- After resolving conflicts with upstream
- After reordering commits

## See also

- [log](log.md) - Verify stack structure after rebase
- [rebase](rebase.md) - Generate a rebase script for manual control
63 changes: 63 additions & 0 deletions docs/land.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# gh-stack land

Merge an entire stack by squash-merging the topmost approved PR and closing the rest.

## Usage

```bash
gh-stack land 'STACK-ID'
gh-stack land 'STACK-ID' --dry-run # preview without changes
gh-stack land 'STACK-ID' --count 2 # only land bottom 2 PRs
gh-stack land 'STACK-ID' --no-approval # skip approval check
```

## How it works

1. Orders the stack from base to top
2. Finds the topmost PR that can be merged (approved, not draft)
3. Squash-merges that PR into its base
4. Closes all PRs below it with a comment linking to the merge

This works because each PR contains all commits from PRs below it. Squash-merging the top PR lands all changes at once.

## Flags

| Flag | Description |
|------|-------------|
| `--dry-run` | Preview what would happen without making changes |
| `--count N` | Only land the bottom N PRs in the stack |
| `--no-approval` | Skip the approval requirement check |
| `-r`, `--repository` | Override repository (owner/repo) |
| `-o`, `--origin` | Git remote name (default: origin) |
| `-e`, `--excl` | Exclude PR by number (repeatable) |

## Requirements

- PRs must be approved (unless `--no-approval`)
- Draft PRs block landing
- The PR being merged must pass branch protection rules

## Example

```
Stack before:
#103 [STACK-ID] Part 3 (approved)
#102 [STACK-ID] Part 2 (approved)
#101 [STACK-ID] Part 1 (approved, base: main)

After `gh-stack land 'STACK-ID'`:
#103 squash-merged into main
#102 closed (comment: "Landed via #103")
#101 closed (comment: "Landed via #103")
```

## When to use

- All PRs in the stack are approved
- CI is passing on the top PR
- Ready to merge to main/master

## See also

- [log](log.md) - Check stack status before landing
- [annotate](annotate.md) - Update PR descriptions
71 changes: 71 additions & 0 deletions docs/log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# gh-stack log

Visualize your stack's structure and status.

## Usage

```bash
gh-stack log 'STACK-ID'
gh-stack log 'STACK-ID' --short # compact list view
gh-stack log 'STACK-ID' --include-closed # show closed/merged PRs
gh-stack log 'STACK-ID' --no-color # disable colors and unicode
gh-stack log 'STACK-ID' -C /path/to/repo # specify repo path
```

## Output

The default tree view shows:

```
◉ feat/part-3 (current)
│ 2 hours ago
│ a1b2c3d - Add validation logic
│ f4e5d6c - Update tests
◯ feat/part-2
│ 3 hours ago
◯ feat/part-1 (draft)
│ 5 hours ago
◯ main
```

- `◉` marks the current branch
- `◯` marks other branches
- Commits are shown when run from a git repo
- Timestamps show when each PR was last updated
- Draft PRs are labeled

The `--short` flag shows a compact list:

```
#103: [STACK-ID] Add validation (Merges into #102)
#102: [STACK-ID] Implement feature (Merges into #101)
#101: [STACK-ID] Initial scaffolding (Base)
```

## Flags

| Flag | Description |
|------|-------------|
| `--short`, `-s` | Compact list format instead of tree |
| `--include-closed` | Show branches with closed/merged PRs |
| `--no-color` | Disable colors and unicode characters |
| `-C`, `--project` | Path to local repository |
| `-r`, `--repository` | Override repository (owner/repo) |
| `-o`, `--origin` | Git remote name (default: origin) |
| `-e`, `--excl` | Exclude PR by number (repeatable) |

## When to use

- Before rebasing to understand stack structure
- To check which PRs are open, merged, or draft
- To see recent commits on each branch
- To verify stack order before landing

## See also

- [annotate](annotate.md) - Add stack tables to PR descriptions
- [land](land.md) - Merge the stack
45 changes: 45 additions & 0 deletions docs/rebase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# gh-stack rebase

Generate a bash script to manually rebase a stack.

## Usage

```bash
gh-stack rebase 'STACK-ID' > rebase.sh
chmod +x rebase.sh
./rebase.sh
```

## How it works

Outputs a bash script with git commands to:

1. Check out each branch in order
2. Rebase onto the previous branch
3. Handle the stack reconstruction step-by-step

This gives you full control over the rebase process.

## Flags

| Flag | Description |
|------|-------------|
| `-e`, `--excl` | Exclude PR by number (repeatable) |

## When to use

- When `autorebase` doesn't fit your workflow
- When you need to inspect/modify the rebase steps
- For debugging stack issues
- When you want to dry-run before executing

## Warnings

- The generated script may need manual adjustments
- Review the script before executing
- Back up your work first

## See also

- [autorebase](autorebase.md) - Automatic stack rebuilding
- [log](log.md) - Verify stack structure
Loading