Initial commit
This commit is contained in:
11
.claude-plugin/plugin.json
Normal file
11
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "git-chain",
|
||||
"description": "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 rebasing or merging entire branch chains.",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Alberto Leal"
|
||||
},
|
||||
"skills": [
|
||||
"./"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# 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 rebasing or merging entire branch chains.
|
||||
232
SKILL.md
Normal file
232
SKILL.md
Normal file
@@ -0,0 +1,232 @@
|
||||
---
|
||||
name: git-chain
|
||||
description: 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 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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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 `main` or `master`) - NOT part of the chain
|
||||
- **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:
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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)**
|
||||
```bash
|
||||
git chain rebase
|
||||
```
|
||||
|
||||
**Option B: Merge (preserves history, creates merge commits)**
|
||||
```bash
|
||||
git chain merge
|
||||
```
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Pattern 1: Stacked PR Workflow
|
||||
|
||||
**Scenario**: Working on a feature split into 3 PRs: auth, profiles, settings
|
||||
|
||||
```bash
|
||||
# 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)
|
||||
|
||||
```bash
|
||||
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`
|
||||
|
||||
```bash
|
||||
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 |
|
||||
|---------|-------------|
|
||||
| `git chain setup <name> <root> <b1> <b2>...` | Create chain with branches |
|
||||
| `git chain init <name> <root>` | Add current branch to chain |
|
||||
| `git chain` | Display current chain |
|
||||
| `git chain list` | List all chains |
|
||||
| `git chain rebase` | Rebase all branches (rewrites history) |
|
||||
| `git chain merge` | Merge all branches (preserves history) |
|
||||
| `git chain push` | Push all branches to remotes |
|
||||
| `git chain push --force` | Force push all branches |
|
||||
| `git chain first/last/next/prev` | Navigate between chain branches |
|
||||
| `git chain backup` | Create backup branches |
|
||||
| `git chain prune` | Remove branches merged to root |
|
||||
| `git chain remove` | Remove current branch from chain |
|
||||
| `git chain remove --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](references/rebase-options.md) - All rebase flags and conflict handling
|
||||
- [references/merge-options.md](references/merge-options.md) - All merge flags and strategies
|
||||
- [references/chain-management.md](references/chain-management.md) - Moving, reorganizing, and removing chains
|
||||
|
||||
**Key flags:**
|
||||
- `--step, -s`: Process one branch at a time (rebase)
|
||||
- `--ignore-root, -i`: Skip updating first branch from root
|
||||
- `--verbose, -v`: Detailed output (merge)
|
||||
- `--chain=<name>`: Operate on specific chain
|
||||
- `--no-ff`: Force merge commits even for fast-forwards
|
||||
- `--squashed-merge=<mode>`: Handle squash-merged branches (reset/skip/merge)
|
||||
|
||||
## Recovery
|
||||
|
||||
If something goes wrong during rebase:
|
||||
|
||||
```bash
|
||||
# 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`:
|
||||
|
||||
1. Git-chain pauses at the conflicted commit
|
||||
2. Resolve conflicts manually in the marked files
|
||||
3. `git add <resolved-files>`
|
||||
4. `git rebase --continue`
|
||||
5. `git chain rebase` (continues with remaining branches)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**"Branch not part of any chain"**
|
||||
- Run `git chain list` to see available chains
|
||||
- Use `git chain init` to add the current branch to a chain
|
||||
|
||||
**"Cannot find fork-point"**
|
||||
- Reflog may have been cleaned up
|
||||
- Use `--no-fork-point` flag to fall back to merge-base
|
||||
|
||||
**Rebase conflicts on every update**
|
||||
- Consider using `git chain merge` instead to preserve history
|
||||
- Or use `--step` flag to handle each branch individually
|
||||
|
||||
**Squash-merged branch causing issues**
|
||||
- git-chain detects squash merges; use `--squashed-merge=skip` to skip them
|
||||
- Or use `--squashed-merge=reset` (default) to reset branch to parent
|
||||
57
plugin.lock.json
Normal file
57
plugin.lock.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:dashed/claude-marketplace:plugins/git-chain",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "31620de9b4de693bdf3658e820ff37052ce78354",
|
||||
"treeHash": "b2dcf1bfb68949a23c86b6ca02bc263db9b5d76a8d1618efe0f8511b749607fe",
|
||||
"generatedAt": "2025-11-28T10:16:05.384798Z",
|
||||
"toolVersion": "publish_plugins.py@0.2.0"
|
||||
},
|
||||
"origin": {
|
||||
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||
"branch": "master",
|
||||
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "git-chain",
|
||||
"description": "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 rebasing or merging entire branch chains.",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "d1b31cca4736be73aae918113098bdeb038563f488d58c6992ec0b21bedff298"
|
||||
},
|
||||
{
|
||||
"path": "SKILL.md",
|
||||
"sha256": "855735eb9ab1230e4ebaace043e6fe9f691f412c0929c03bbf0fb6e6909ca624"
|
||||
},
|
||||
{
|
||||
"path": "references/chain-management.md",
|
||||
"sha256": "eaae153f66344982779b43ac4c33f7867c0b93bbc3f203848e27a1e2742cf969"
|
||||
},
|
||||
{
|
||||
"path": "references/rebase-options.md",
|
||||
"sha256": "09f0785f48cfd81aa5c6268d6d47d12f26e62589467ad4e10d70fc769fd322c4"
|
||||
},
|
||||
{
|
||||
"path": "references/merge-options.md",
|
||||
"sha256": "104a005e1b8f624c97562304084c917d6f52e4e3f8a93a1840b1ceff1252eed2"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "2d6ba42fa7c87b671e3a6241aef1b939517068a2d3b82f159ef1041d55d59ca0"
|
||||
}
|
||||
],
|
||||
"dirSha256": "b2dcf1bfb68949a23c86b6ca02bc263db9b5d76a8d1618efe0f8511b749607fe"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
315
references/chain-management.md
Normal file
315
references/chain-management.md
Normal file
@@ -0,0 +1,315 @@
|
||||
# Git Chain Management
|
||||
|
||||
Comprehensive reference for creating, modifying, and navigating branch chains.
|
||||
|
||||
## Creating Chains
|
||||
|
||||
### git chain setup
|
||||
|
||||
Create a new chain with multiple branches at once.
|
||||
|
||||
```bash
|
||||
git chain setup <chain_name> <root_branch> <branch_1> <branch_2> ... <branch_N>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
git chain setup user-feature main auth profiles settings
|
||||
```
|
||||
|
||||
Creates chain "user-feature" with:
|
||||
- Root: `main` (not part of the chain)
|
||||
- Order: `auth` -> `profiles` -> `settings`
|
||||
|
||||
### git chain init
|
||||
|
||||
Add the current branch to a chain.
|
||||
|
||||
```bash
|
||||
# Add to end of chain (default)
|
||||
git chain init <chain_name> <root_branch>
|
||||
|
||||
# Add at specific position
|
||||
git chain init <chain_name> <root_branch> --before=<other_branch>
|
||||
git chain init <chain_name> <root_branch> --after=<other_branch>
|
||||
git chain init <chain_name> <root_branch> --first
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Add current branch at end
|
||||
git checkout notifications
|
||||
git chain init user-feature main
|
||||
|
||||
# Add before settings
|
||||
git chain init user-feature main --before=settings
|
||||
|
||||
# Add after profiles
|
||||
git chain init user-feature main --after=profiles
|
||||
|
||||
# Add as first branch in chain
|
||||
git chain init user-feature main --first
|
||||
```
|
||||
|
||||
## Viewing Chains
|
||||
|
||||
### git chain
|
||||
|
||||
Display the current chain (if current branch is part of one).
|
||||
|
||||
```bash
|
||||
git chain
|
||||
```
|
||||
|
||||
Shows:
|
||||
- Chain name
|
||||
- Root branch
|
||||
- All branches in order
|
||||
- Current branch indicator
|
||||
|
||||
### git chain list
|
||||
|
||||
List all chains in the repository.
|
||||
|
||||
```bash
|
||||
git chain list
|
||||
```
|
||||
|
||||
## Modifying Chains
|
||||
|
||||
### git chain move
|
||||
|
||||
Move a branch within its chain or to a different chain.
|
||||
|
||||
```bash
|
||||
# Move to different position in same chain
|
||||
git chain move --before=<other_branch>
|
||||
git chain move --after=<other_branch>
|
||||
|
||||
# Move to different chain
|
||||
git chain move --chain=<other_chain_name>
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Move current branch before settings
|
||||
git chain move --before=settings
|
||||
|
||||
# Move current branch after auth
|
||||
git chain move --after=auth
|
||||
|
||||
# Move to a different chain
|
||||
git chain move --chain=api-feature
|
||||
```
|
||||
|
||||
### git chain rename
|
||||
|
||||
Rename the current chain.
|
||||
|
||||
```bash
|
||||
git chain rename <new_chain_name>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
git chain rename user-management
|
||||
```
|
||||
|
||||
## Removing from Chains
|
||||
|
||||
### git chain remove
|
||||
|
||||
Remove the current branch from its chain.
|
||||
|
||||
```bash
|
||||
git chain remove
|
||||
```
|
||||
|
||||
**Note:** This only removes the branch from the chain metadata. The branch itself still exists.
|
||||
|
||||
### git chain remove --chain
|
||||
|
||||
Remove the entire chain.
|
||||
|
||||
```bash
|
||||
# Remove the current chain
|
||||
git chain remove --chain
|
||||
|
||||
# Remove a specific chain
|
||||
git chain remove --chain=<chain_name>
|
||||
```
|
||||
|
||||
**Note:** This removes the chain metadata only. All branches continue to exist.
|
||||
|
||||
## Chain Navigation
|
||||
|
||||
Navigate between branches in a chain without remembering branch names.
|
||||
|
||||
### git chain first
|
||||
|
||||
Switch to the first branch in the chain.
|
||||
|
||||
```bash
|
||||
git chain first
|
||||
```
|
||||
|
||||
### git chain last
|
||||
|
||||
Switch to the last branch in the chain.
|
||||
|
||||
```bash
|
||||
git chain last
|
||||
```
|
||||
|
||||
### git chain next
|
||||
|
||||
Switch to the next branch in the chain.
|
||||
|
||||
```bash
|
||||
git chain next
|
||||
```
|
||||
|
||||
### git chain prev
|
||||
|
||||
Switch to the previous branch in the chain.
|
||||
|
||||
```bash
|
||||
git chain prev
|
||||
```
|
||||
|
||||
**Navigation Example:**
|
||||
```bash
|
||||
# Chain: auth -> profiles -> settings
|
||||
# Currently on: profiles
|
||||
|
||||
git chain next # Switches to settings
|
||||
git chain prev # Switches back to profiles
|
||||
git chain first # Switches to auth
|
||||
git chain last # Switches to settings
|
||||
```
|
||||
|
||||
## Utility Commands
|
||||
|
||||
### git chain backup
|
||||
|
||||
Create backup branches for all branches in the chain.
|
||||
|
||||
```bash
|
||||
git chain backup
|
||||
```
|
||||
|
||||
Creates branches named `<branch-name>-backup` for each branch.
|
||||
|
||||
**Use before:**
|
||||
- Complex rebases
|
||||
- Experimental changes
|
||||
- When you want a safety net
|
||||
|
||||
### git chain push
|
||||
|
||||
Push all branches in the chain to their remotes.
|
||||
|
||||
```bash
|
||||
# Normal push
|
||||
git chain push
|
||||
|
||||
# Force push (uses --force-with-lease for safety)
|
||||
git chain push --force
|
||||
```
|
||||
|
||||
**Useful for:**
|
||||
- Updating all PRs at once
|
||||
- After rebasing the chain
|
||||
|
||||
### git chain prune
|
||||
|
||||
Remove branches that have been merged to the root branch.
|
||||
|
||||
```bash
|
||||
git chain prune
|
||||
```
|
||||
|
||||
Detects and removes branches whose changes are already in the root branch.
|
||||
|
||||
## Chain Storage
|
||||
|
||||
Git chain stores relationships in your repository's Git config:
|
||||
- Which chain a branch belongs to
|
||||
- The order of branches within a chain
|
||||
- Each branch's root branch
|
||||
|
||||
You can view this with:
|
||||
```bash
|
||||
git config --get-regexp chain
|
||||
```
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### Creating a Feature Chain from Scratch
|
||||
|
||||
```bash
|
||||
# Create base branch
|
||||
git checkout -b auth main
|
||||
# ... develop auth feature ...
|
||||
git commit -m "Add authentication"
|
||||
|
||||
# Create dependent branch
|
||||
git checkout -b profiles auth
|
||||
# ... develop profiles feature ...
|
||||
git commit -m "Add user profiles"
|
||||
|
||||
# Create another dependent branch
|
||||
git checkout -b settings profiles
|
||||
# ... develop settings feature ...
|
||||
git commit -m "Add settings page"
|
||||
|
||||
# Set up the chain
|
||||
git chain setup user-features main auth profiles settings
|
||||
```
|
||||
|
||||
### Inserting a Branch Mid-Chain
|
||||
|
||||
```bash
|
||||
# Need to add notifications between profiles and settings
|
||||
git checkout -b notifications profiles
|
||||
# ... develop notifications ...
|
||||
git commit -m "Add notifications"
|
||||
|
||||
# Add to chain in correct position
|
||||
git chain init user-features main --after=profiles
|
||||
```
|
||||
|
||||
### Reorganizing a Chain
|
||||
|
||||
```bash
|
||||
# Move notifications to be first
|
||||
git checkout notifications
|
||||
git chain move --before=auth
|
||||
|
||||
# Or move to after settings
|
||||
git chain move --after=settings
|
||||
```
|
||||
|
||||
### Cleaning Up After Merges
|
||||
|
||||
```bash
|
||||
# After auth PR is merged to main
|
||||
git chain prune # Removes auth from chain
|
||||
|
||||
# Chain is now: profiles -> settings (with main as root)
|
||||
```
|
||||
|
||||
### Splitting a Chain
|
||||
|
||||
```bash
|
||||
# Remove middle branch to create two chains
|
||||
git checkout profiles
|
||||
git chain remove
|
||||
|
||||
# Now auth is alone in user-features chain
|
||||
# Create new chain for profiles and settings
|
||||
git checkout profiles
|
||||
git chain init profile-features main
|
||||
git checkout settings
|
||||
git chain init profile-features main --after=profiles
|
||||
```
|
||||
290
references/merge-options.md
Normal file
290
references/merge-options.md
Normal file
@@ -0,0 +1,290 @@
|
||||
# Git Chain Merge Options
|
||||
|
||||
Comprehensive reference for `git chain merge` command options, strategies, and reporting.
|
||||
|
||||
## How Merge Works
|
||||
|
||||
Git chain merge updates each branch by merging the parent branch into it:
|
||||
1. Checks out each branch in chain order
|
||||
2. Merges the parent branch into it
|
||||
3. Creates merge commits (unless fast-forward is possible)
|
||||
|
||||
Unlike rebase, merge preserves the original commit history.
|
||||
|
||||
## Basic Options
|
||||
|
||||
### --verbose, -v
|
||||
|
||||
Provides detailed output during the merging process.
|
||||
|
||||
```bash
|
||||
git chain merge --verbose
|
||||
```
|
||||
|
||||
Shows exactly what's happening with each branch, including Git's merge output.
|
||||
|
||||
### --ignore-root, -i
|
||||
|
||||
Skips merging the root branch into the first chain branch.
|
||||
|
||||
```bash
|
||||
git chain merge --ignore-root
|
||||
```
|
||||
|
||||
**Use when:**
|
||||
- Only want to propagate changes between chain branches
|
||||
- Root branch has changes you don't want incorporated yet
|
||||
|
||||
### --stay
|
||||
|
||||
Don't return to the original branch after merging.
|
||||
|
||||
```bash
|
||||
git chain merge --stay
|
||||
```
|
||||
|
||||
By default, git-chain returns you to your starting branch. Use this flag to remain on the last merged branch.
|
||||
|
||||
### --chain=<name>
|
||||
|
||||
Operate on a specific chain other than the current one.
|
||||
|
||||
```bash
|
||||
git chain merge --chain=feature-x
|
||||
```
|
||||
|
||||
Allows merging a chain even when not on a branch that belongs to it.
|
||||
|
||||
## Merge Behavior Controls
|
||||
|
||||
### --simple, -s
|
||||
|
||||
Use simple merge mode without advanced detection.
|
||||
|
||||
```bash
|
||||
git chain merge --simple
|
||||
```
|
||||
|
||||
Disables fork-point detection and squashed merge handling for a faster, simpler merge process.
|
||||
|
||||
### --fork-point, -f
|
||||
|
||||
Use Git's fork-point detection (default behavior).
|
||||
|
||||
```bash
|
||||
git chain merge --fork-point
|
||||
```
|
||||
|
||||
Explicitly enables fork-point detection for finding better merge bases.
|
||||
|
||||
### --no-fork-point
|
||||
|
||||
Disable fork-point detection, use regular merge-base.
|
||||
|
||||
```bash
|
||||
git chain merge --no-fork-point
|
||||
```
|
||||
|
||||
Can be faster but potentially less accurate. Useful for repositories with limited reflog history.
|
||||
|
||||
### --squashed-merge=<mode>
|
||||
|
||||
How to handle branches that appear squash-merged.
|
||||
|
||||
```bash
|
||||
# Reset branch to match parent (default)
|
||||
git chain merge --squashed-merge=reset
|
||||
|
||||
# Skip branches that appear squashed
|
||||
git chain merge --squashed-merge=skip
|
||||
|
||||
# Force merge despite detection
|
||||
git chain merge --squashed-merge=merge
|
||||
```
|
||||
|
||||
## Git Merge Options
|
||||
|
||||
### Fast-Forward Behavior
|
||||
|
||||
```bash
|
||||
# Allow fast-forward if possible (default)
|
||||
git chain merge --ff
|
||||
|
||||
# Always create a merge commit
|
||||
git chain merge --no-ff
|
||||
|
||||
# Only allow fast-forward merges (fail if real merge needed)
|
||||
git chain merge --ff-only
|
||||
```
|
||||
|
||||
### --squash
|
||||
|
||||
Create a single commit instead of a merge commit.
|
||||
|
||||
```bash
|
||||
git chain merge --squash
|
||||
```
|
||||
|
||||
Combines all changes from the source branch into a single commit.
|
||||
|
||||
### --strategy=<strategy>
|
||||
|
||||
Use a specific Git merge strategy.
|
||||
|
||||
```bash
|
||||
git chain merge --strategy=recursive
|
||||
git chain merge --strategy=ours
|
||||
git chain merge --strategy=resolve
|
||||
```
|
||||
|
||||
Available strategies:
|
||||
- `recursive` (default) - 3-way merge
|
||||
- `resolve` - 3-way merge with fewer renames
|
||||
- `ours` - Keep our version for all conflicts
|
||||
- `octopus` - For merging more than two heads
|
||||
|
||||
### --strategy-option=<option>
|
||||
|
||||
Pass strategy-specific options.
|
||||
|
||||
```bash
|
||||
# Ignore whitespace changes
|
||||
git chain merge --strategy=recursive --strategy-option=ignore-space-change
|
||||
|
||||
# Use patience diff algorithm
|
||||
git chain merge --strategy=recursive --strategy-option=patience
|
||||
|
||||
# Prefer ours in conflicts
|
||||
git chain merge --strategy=recursive --strategy-option=ours
|
||||
```
|
||||
|
||||
## Reporting Options
|
||||
|
||||
### --report-level=<level>
|
||||
|
||||
Adjust the level of detail in the merge report.
|
||||
|
||||
```bash
|
||||
# Basic success/failure messages
|
||||
git chain merge --report-level=minimal
|
||||
|
||||
# Summary with counts (default)
|
||||
git chain merge --report-level=standard
|
||||
|
||||
# Comprehensive per-branch details
|
||||
git chain merge --report-level=detailed
|
||||
```
|
||||
|
||||
### --no-report
|
||||
|
||||
Suppress the merge summary report entirely.
|
||||
|
||||
```bash
|
||||
git chain merge --no-report
|
||||
```
|
||||
|
||||
### --detailed-report
|
||||
|
||||
Same as `--report-level=detailed`.
|
||||
|
||||
```bash
|
||||
git chain merge --detailed-report
|
||||
```
|
||||
|
||||
## Conflict Handling
|
||||
|
||||
### When Conflicts Occur
|
||||
|
||||
1. Git chain stops at the conflicted branch
|
||||
2. Repository is left in conflicted state
|
||||
3. Shows which branches conflicted and which files
|
||||
|
||||
### Resolution Process
|
||||
|
||||
```bash
|
||||
# 1. See conflicted files
|
||||
git status
|
||||
|
||||
# 2. Resolve conflicts (edit files, remove markers)
|
||||
vim <conflicted-file>
|
||||
|
||||
# 3. Stage resolved files
|
||||
git add <resolved-files>
|
||||
|
||||
# 4. Complete the merge
|
||||
git commit
|
||||
|
||||
# 5. Continue with remaining branches
|
||||
git chain merge
|
||||
```
|
||||
|
||||
### Example Conflict Output
|
||||
|
||||
```
|
||||
Processing branch: feature/auth
|
||||
Merge made by the 'recursive' strategy.
|
||||
src/config.js | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
Processing branch: feature/profiles
|
||||
Merge conflict between feature/auth and feature/profiles:
|
||||
Auto-merging src/models/user.js
|
||||
CONFLICT (content): Merge conflict in src/models/user.js
|
||||
|
||||
Merge Summary for Chain: feature
|
||||
Successful merges: 1
|
||||
Merge conflicts: 1
|
||||
- feature/auth into feature/profiles
|
||||
```
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### Update Open PRs Without Breaking Comments
|
||||
|
||||
```bash
|
||||
# Merge preserves commits, keeping PR review comments
|
||||
git chain merge
|
||||
git chain push
|
||||
```
|
||||
|
||||
### Update Specific Chain While on Unrelated Branch
|
||||
|
||||
```bash
|
||||
git chain merge --chain=feature-login --verbose
|
||||
```
|
||||
|
||||
### Clean History With No Extra Merge Commits
|
||||
|
||||
```bash
|
||||
git chain merge --ff-only
|
||||
```
|
||||
|
||||
Only updates branches that can be fast-forwarded.
|
||||
|
||||
### Handle Squashed Branches
|
||||
|
||||
```bash
|
||||
# Skip branches that appear squash-merged
|
||||
git chain merge --squashed-merge=skip
|
||||
```
|
||||
|
||||
### Maximum Information for Complex Merges
|
||||
|
||||
```bash
|
||||
git chain merge --verbose --detailed-report
|
||||
```
|
||||
|
||||
## When to Use Merge vs Rebase
|
||||
|
||||
### Use Merge When:
|
||||
- Branches have open pull requests with review comments
|
||||
- You want to preserve complete development history
|
||||
- Need to maintain context of commits for reviewers
|
||||
- Collaborating with others on the same branches
|
||||
- Branches have already been pushed/shared
|
||||
|
||||
### Use Rebase When:
|
||||
- Working on private branches that haven't been shared
|
||||
- You prefer a linear, cleaner history
|
||||
- PRs haven't been reviewed yet
|
||||
- Want each branch's changes to appear fresh
|
||||
205
references/rebase-options.md
Normal file
205
references/rebase-options.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# Git Chain Rebase Options
|
||||
|
||||
Comprehensive reference for `git chain rebase` command options and conflict handling.
|
||||
|
||||
## How Rebase Works
|
||||
|
||||
Git chain rebase updates each branch in sequence by:
|
||||
1. Finding the fork-point (where branch diverged from parent)
|
||||
2. Rebasing branch commits onto the updated parent
|
||||
3. Moving to the next branch in the chain
|
||||
|
||||
The underlying command is:
|
||||
```bash
|
||||
git rebase --keep-empty --onto <parent_branch> <fork_point> <branch>
|
||||
```
|
||||
|
||||
## Command Options
|
||||
|
||||
### --step, -s
|
||||
|
||||
Rebase one branch at a time, requiring manual confirmation between steps.
|
||||
|
||||
```bash
|
||||
git chain rebase --step
|
||||
```
|
||||
|
||||
**Use when:**
|
||||
- Anticipating conflicts and want to handle each branch separately
|
||||
- Need to review changes before proceeding to next branch
|
||||
- Debugging issues in the rebase process
|
||||
|
||||
### --ignore-root, -i
|
||||
|
||||
Skip rebasing the first branch onto the root branch.
|
||||
|
||||
```bash
|
||||
git chain rebase --ignore-root
|
||||
```
|
||||
|
||||
**Use when:**
|
||||
- Only want to update relationships between chain branches
|
||||
- Root branch has changes you don't want to incorporate yet
|
||||
- Testing chain structure without full update
|
||||
|
||||
### Combined Options
|
||||
|
||||
```bash
|
||||
# Step through without updating from root
|
||||
git chain rebase --step --ignore-root
|
||||
```
|
||||
|
||||
## Fork-Point Detection
|
||||
|
||||
Git chain uses sophisticated fork-point detection:
|
||||
|
||||
1. **First**: Checks if branch can be fast-forwarded
|
||||
2. **Then**: Uses Git's reflog to find original branching point
|
||||
3. **Fallback**: Uses regular merge-base if fork-point fails
|
||||
|
||||
### When Fork-Point Detection Fails
|
||||
|
||||
Fork-point may fail when:
|
||||
- Reflog entries have been cleaned by `git gc`
|
||||
- Branch was created from an older commit (not tip) of parent
|
||||
- Repository history was affected by certain operations
|
||||
|
||||
In these cases, git-chain falls back to `git merge-base` which finds the most recent common ancestor.
|
||||
|
||||
## Squash Merge Detection
|
||||
|
||||
Git chain detects when a branch has been squash-merged into its parent:
|
||||
- Compares the diff between branch and parent
|
||||
- If empty diff, assumes branch was squash-merged
|
||||
- Prevents duplicate changes from being rebased
|
||||
|
||||
## Conflict Handling
|
||||
|
||||
### When Conflicts Occur
|
||||
|
||||
1. **Detection**: Git chain stops at the conflicted commit
|
||||
2. **State**: Repository is left in conflicted state for resolution
|
||||
3. **Information**: Shows which branch is being rebased and conflict location
|
||||
4. **Backups**: May create automatic backup branches
|
||||
|
||||
### Resolution Steps
|
||||
|
||||
```bash
|
||||
# 1. See which files are conflicted
|
||||
git status
|
||||
|
||||
# 2. Edit conflicted files (look for markers)
|
||||
# <<<<<<<, =======, >>>>>>>
|
||||
|
||||
# 3. Mark as resolved
|
||||
git add <resolved-files>
|
||||
|
||||
# 4. Continue the rebase
|
||||
git rebase --continue
|
||||
|
||||
# 5. Continue with remaining chain branches
|
||||
git chain rebase
|
||||
```
|
||||
|
||||
### Aborting a Rebase
|
||||
|
||||
If conflicts are too complex or you need to reconsider:
|
||||
|
||||
```bash
|
||||
# Abort current rebase
|
||||
git rebase --abort
|
||||
|
||||
# If backup branches exist, restore
|
||||
git checkout branch-name
|
||||
git reset --hard branch-name-backup
|
||||
```
|
||||
|
||||
## Example Workflows
|
||||
|
||||
### Standard Chain Update
|
||||
|
||||
```bash
|
||||
# Update all branches from root through chain
|
||||
git chain rebase
|
||||
```
|
||||
|
||||
### Careful Rebase with Review
|
||||
|
||||
```bash
|
||||
# Process one branch at a time
|
||||
git chain rebase --step
|
||||
|
||||
# After each branch:
|
||||
# - Review the rebased commits
|
||||
# - Run tests
|
||||
# - Press Enter to continue or Ctrl+C to stop
|
||||
```
|
||||
|
||||
### Internal Chain Update Only
|
||||
|
||||
```bash
|
||||
# Update branch relationships without incorporating root changes
|
||||
git chain rebase --ignore-root
|
||||
```
|
||||
|
||||
### Conflict Workflow Example
|
||||
|
||||
```bash
|
||||
$ git chain rebase
|
||||
Rebasing branch feature/auth onto master...
|
||||
Auto-merging src/auth.js
|
||||
CONFLICT (content): Merge conflict in src/auth.js
|
||||
error: could not apply 1a2b3c4... Add authentication feature
|
||||
|
||||
# Resolve the conflict
|
||||
$ vim src/auth.js
|
||||
$ git add src/auth.js
|
||||
$ git rebase --continue
|
||||
Successfully rebased branch feature/auth
|
||||
|
||||
# Git chain continues automatically
|
||||
Rebasing branch feature/profiles onto feature/auth...
|
||||
Successfully rebased branch feature/profiles
|
||||
```
|
||||
|
||||
## Recovery Options
|
||||
|
||||
### From Backup Branches
|
||||
|
||||
If you used `git chain backup` before rebasing:
|
||||
|
||||
```bash
|
||||
git checkout branch-name
|
||||
git reset --hard branch-name-backup
|
||||
|
||||
# Clean up backup after restoring
|
||||
git branch -D branch-name-backup
|
||||
```
|
||||
|
||||
### From Reflog
|
||||
|
||||
Even without backups, Git's reflog tracks all branch movements:
|
||||
|
||||
```bash
|
||||
# See branch history
|
||||
git reflog show branch-name
|
||||
|
||||
# Reset to previous state
|
||||
git checkout branch-name
|
||||
git reset --hard branch-name@{1} # Previous state
|
||||
git reset --hard branch-name@{2} # Two states ago
|
||||
```
|
||||
|
||||
### Abort In-Progress Rebase
|
||||
|
||||
```bash
|
||||
git rebase --abort
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Create backups first**: `git chain backup` before complex rebases
|
||||
2. **Use --step for complex chains**: Easier to handle conflicts one branch at a time
|
||||
3. **Run tests after rebase**: Ensure nothing broke during the update
|
||||
4. **Don't rebase shared branches**: Only rebase private/local branches
|
||||
5. **Pull before rebase**: Ensure root branch is up to date
|
||||
Reference in New Issue
Block a user