Claude-skill-registry git-chain
Manage and rebase chains of dependent Git branches (stacked branches). Use when working with multiple dependent PRs, feature branches that build on each other, or maintaining clean branch hierarchies. Automates the tedious process of rebasing or merging entire branch chains.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/git-chain" ~/.claude/skills/majiayu000-claude-skill-registry-git-chain && rm -rf "$T"
skills/data/git-chain/SKILL.mdGit Chain
Overview
git chain manages chains of dependent Git branches where each branch builds upon the previous one (stacked branches). Instead of manually rebasing each branch in sequence, git-chain tracks relationships and updates all branches with a single command.
I---J---K feature-2 / E---F---G feature-1 / A---B---C---D master
When
master is updated, git-chain rebases feature-1 onto master, then feature-2 onto feature-1 automatically.
When to Use This Skill
Use git-chain when:
- Stacked PRs: Working with multiple dependent pull requests that build on each other
- Feature chains: Developing a large feature split into incremental branches
- Review feedback: Updating base branches requires propagating changes to dependent branches
- Clean history: Maintaining linear commit history across dependent branches
- Avoiding tedious rebasing: Don't want to manually rebase 3+ branches in sequence
Prerequisites
CRITICAL: Before proceeding, verify that git-chain is installed:
git chain --version
If git-chain is not installed:
- DO NOT attempt to install it automatically
- STOP and inform the user that git-chain is required
- RECOMMEND manual installation:
# From source (requires Rust) git clone git@github.com:dashed/git-chain.git cd git-chain make install # Or with Cargo cargo install --path .
If git-chain is not available, exit gracefully and do not proceed with the workflow below.
Key Concepts
- Chain: A named sequence of branches with dependency order
- Root Branch: Foundation branch (typically
ormain
) - NOT part of the chainmaster - Branch Order: The sequence in which branches depend on each other
Important: A branch can belong to at most one chain.
Basic Workflow
Step 1: Set Up a Chain
Create a chain with your stacked branches:
git chain setup my-feature master feature-1 feature-2 feature-3
This creates chain "my-feature" with
master as root and branches in order: feature-1 -> feature-2 -> feature-3.
Step 2: View the Chain
git chain # Show current chain (if on a chain branch) git chain list # List all chains in the repository
Step 3: Update the Chain
When the root branch or any branch in the chain has new commits:
Option A: Rebase (rewrites history, clean linear commits)
git chain rebase
Option B: Merge (preserves history, creates merge commits)
git chain merge
Common Patterns
Pattern 1: Stacked PR Workflow
Scenario: Working on a feature split into 3 PRs: auth, profiles, settings
# Create branches git checkout -b auth main # ... make auth changes, commit ... git checkout -b profiles auth # ... make profile changes, commit ... git checkout -b settings profiles # ... make settings changes, commit ... # Set up the chain git chain setup user-feature main auth profiles settings # After main receives new commits, update all branches git chain rebase git chain push --force # Update all PRs
Pattern 2: Review Feedback on Base Branch
Scenario: Reviewer requested changes on
auth branch (first PR)
git checkout auth # ... make changes, commit ... # Update dependent branches automatically git chain rebase
Pattern 3: Adding a New Branch to Existing Chain
Scenario: Need to add
notifications branch between profiles and settings
git checkout -b notifications profiles # ... make changes, commit ... # Add to chain with specific position git chain init user-feature main --after=profiles
Core Commands Reference
| Command | Description |
|---|---|
| Create chain with branches |
| Add current branch to chain |
| Display current chain |
| List all chains |
| Rebase all branches (rewrites history) |
| Merge all branches (preserves history) |
| Push all branches to remotes |
| Force push all branches |
| Navigate between chain branches |
| Create backup branches |
| Remove branches merged to root |
| Remove current branch from chain |
| Delete entire chain |
Rebase vs Merge
Use Rebase When:
- Branches are private/not shared
- You prefer clean, linear history
- PRs haven't been reviewed yet
Use Merge When:
- Branches have open PRs with review comments
- You need to preserve commit history
- Collaborating with others on the same branches
Advanced Usage
For comprehensive coverage of all flags and advanced patterns, see:
- references/rebase-options.md - All rebase flags and conflict handling
- references/merge-options.md - All merge flags and strategies
- references/chain-management.md - Moving, reorganizing, and removing chains
Key flags:
: Process one branch at a time (rebase)--step, -s
: Skip updating first branch from root--ignore-root, -i
: Detailed output (merge)--verbose, -v
: Operate on specific chain--chain=<name>
: Force merge commits even for fast-forwards--no-ff
: Handle squash-merged branches (reset/skip/merge)--squashed-merge=<mode>
Recovery
If something goes wrong during rebase:
# Abort in-progress rebase git rebase --abort # Restore from backup (if created with git chain backup) git checkout branch-name git reset --hard branch-name-backup # Or use reflog git reflog git reset --hard branch-name@{1}
Handling Conflicts
When conflicts occur during
git chain rebase:
- Git-chain pauses at the conflicted commit
- Resolve conflicts manually in the marked files
git add <resolved-files>git rebase --continue
(continues with remaining branches)git chain rebase
Troubleshooting
"Branch not part of any chain"
- Run
to see available chainsgit chain list - Use
to add the current branch to a chaingit chain init
"Cannot find fork-point"
- Reflog may have been cleaned up
- Use
flag to fall back to merge-base--no-fork-point
Rebase conflicts on every update
- Consider using
instead to preserve historygit chain merge - Or use
flag to handle each branch individually--step
Squash-merged branch causing issues
- git-chain detects squash merges; use
to skip them--squashed-merge=skip - Or use
(default) to reset branch to parent--squashed-merge=reset