{"id":20614766,"url":"https://github.com/dashed/git-chain","last_synced_at":"2025-08-04T10:35:16.300Z","repository":{"id":42511683,"uuid":"418050228","full_name":"dashed/git-chain","owner":"dashed","description":"🔗 Tool for rebasing a chain of local git branches.","archived":false,"fork":false,"pushed_at":"2024-08-09T10:58:27.000Z","size":153,"stargazers_count":16,"open_issues_count":4,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-09T12:17:29.096Z","etag":null,"topics":["code-review","git","rebase","rust","tool"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dashed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-10-17T07:08:59.000Z","updated_at":"2024-08-09T10:58:18.000Z","dependencies_parsed_at":"2024-03-10T12:21:26.330Z","dependency_job_id":"f13a884e-855c-4dc0-897e-3ed5b3fc132a","html_url":"https://github.com/dashed/git-chain","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dashed%2Fgit-chain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dashed%2Fgit-chain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dashed%2Fgit-chain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dashed%2Fgit-chain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dashed","download_url":"https://codeload.github.com/dashed/git-chain/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224906494,"owners_count":17389902,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-review","git","rebase","rust","tool"],"created_at":"2024-11-16T11:13:33.675Z","updated_at":"2025-04-15T07:33:32.662Z","avatar_url":"https://github.com/dashed.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-chain\n\nA powerful tool for managing and rebasing chains of dependent Git branches (stacked branches).\n\n## What Problem Does Git Chain Solve?\n\nWhen working on complex features, developers often create a series of branches where each branch builds upon the previous one. For example:\n\n```\n                            I---J---K  feature-2\n                           /\n                  E---F---G  feature-1\n                 /\n    A---B---C---D  master\n```\n\nWhen new changes are added to the `master` branch, updating all branches in the chain becomes tedious and error-prone:\n\n1. You need to rebase `feature-1` onto the updated `master`\n2. Then rebase `feature-2` onto the updated `feature-1`\n3. Repeat for any additional branches in the chain\n\nGit Chain automates this entire process. It keeps track of relationships between branches and handles the rebasing for you.\n\n## Key Concepts\n\n- **Chain**: A sequence of branches that build upon each other, with a designated root branch.\n- **Root Branch**: The foundation branch (typically `main` or `master`) that the chain ultimately merges into.\n- **Branch Order**: The sequence in which branches depend on each other in the chain.\n\n**Note**: \n- A branch can belong to at most one chain.\n- The root branch is not part of the chain, but serves as its foundation.\n\n## How Git Chain Works\n\nGit Chain stores branch relationships in your repository's Git config, tracking:\n- Which chain a branch belongs to \n- The order of branches within a chain\n- Each branch's root branch\n\nGit Chain offers two strategies for updating branches:\n1. **Rebase**: Rewrites branch history by replaying commits on top of the updated parent branch\n2. **Merge**: Preserves branch history by creating merge commits that incorporate changes from the parent branch\n\nWhen operating on chains, Git Chain:\n1. Determines the correct fork-point for each branch using `git merge-base --fork-point`\n2. Updates each branch in sequence, preserving the dependency order\n3. Handles edge cases like squash merges and chain reorganization\n\n## Rebase Strategy: How git-chain Updates Your Branches\n\n### Basic Concept\n\nWhen you run `git chain rebase`, git-chain intelligently updates each branch in your chain to incorporate changes from its parent branch. Think of it like moving your work to sit on top of the latest version of your parent branch. This rewrites commit history, giving a cleaner, linear history but generating new commit hashes.\n\n### How It Works\n\n1. **Order Matters**: Branches are updated in the order they appear in the chain, starting from the one closest to the root branch. This ensures each branch builds upon an already-updated parent.\n\n2. **Finding the Right Starting Point**: For each branch, git-chain determines where your branch originally split from its parent. This point (called a \"fork-point\") is crucial for keeping only your changes when rebasing.\n\n   \u003e **What is a fork-point?** A fork-point is the specific commit where you originally created your branch from its parent. It's more intelligent than just finding a common ancestor - Git uses its reflog (a history of where branch tips have been) to determine the exact point where your branch's history forked from the parent branch. This is especially useful when the parent branch has been rebased or reorganized since you created your branch. When rebasing, Git needs to know this point to correctly identify which commits belong to your branch (and should be moved) versus which commits were already in the parent branch (and should be left alone).\n\n3. **Smart Detection**: git-chain uses Git's sophisticated \"fork-point\" detection, which is smarter than simple ancestry checking. It:\n   - First checks if your branch can be simply fast-forwarded\n   - If not, uses Git's history records (reflog) to find the original branching point\n   - Falls back to a regular merge-base if fork-point detection fails\n\n   \u003e **Note on the Fallback Mechanism**: Sometimes Git can't determine the fork-point, particularly in these situations:\n   \u003e - When older reflog entries have been cleaned up by `git gc`\n   \u003e - If you created your branch from an older commit (not the tip) of the parent branch\n   \u003e - After certain operations that affect repository history\n   \u003e\n   \u003e When Git's fork-point detection fails, git-chain automatically falls back to using `git merge-base`, which finds the most recent common ancestor between two branches. While this ensures rebasing can proceed, it might be less precise than using the true fork-point.\n\n4. **Handling Squash Merges**: If you've squash-merged a branch into its parent (combining all commits into one), git-chain detects this and prevents duplicate changes.\n\n5. **The Actual Rebasing**: For each branch, git-chain runs a command similar to:\n   ```\n   git rebase --keep-empty --onto \u003cparent_branch\u003e \u003cfork_point\u003e \u003cbranch\u003e\n   ```\n   This moves your changes to sit on top of the updated parent branch.\n\nTo read more about `fork-point`, see: https://git-scm.com/docs/git-merge-base#_discussion_on_fork_point_mode\n\n### Command Options and Flags\n\nGit Chain's rebase command offers customization through its flags:\n\n- **`--step, -s`**: Rebase one branch at a time, requiring manual confirmation between steps\n  ```\n  git chain rebase --step\n  ```\n  Perfect for carefully managing complex rebases where conflicts might occur.\n\n- **`--ignore-root, -i`**: Skip rebasing the first branch onto the root branch\n  ```\n  git chain rebase --ignore-root\n  ```\n  Useful when you want to update relationships between chain branches without incorporating root branch changes.\n\n### Examples (`git chain rebase`)\n\nHere are some common scenarios and how to handle them with git-chain rebase:\n\n#### 1. Standard chain update\n\n**Scenario**: You want to update all branches in the chain to incorporate changes from their parent branches.\n\n**Solution**:\n```\ngit chain rebase\n```\nThis rebases all branches in the chain sequentially, starting from the one closest to the root branch.\n\n#### 2. Updating just the relationship between chain branches\n\n**Scenario**: You want to update only relationships between branches in a chain, not incorporating new root branch changes.\n\n**Solution**:\n```\ngit chain rebase --ignore-root\n```\nThis skips rebasing the first branch onto the root branch.\n\n#### 3. Careful rebasing with potential conflicts\n\n**Scenario**: You anticipate conflicts and want to handle each branch separately.\n\n**Solution**:\n```\ngit chain rebase --step\n```\nThis rebases one branch at a time, waiting for your confirmation between steps.\n\n### Handling Rebase Conflicts\n\nWhen rebasing branches in a chain, conflicts can sometimes occur. Git Chain handles conflicts as follows:\n\n1. **Conflict Detection**: When a rebase conflict occurs, git-chain:\n   - Pauses the rebasing process at the conflicted commit\n   - Leaves the repository in a conflicted state for you to resolve\n   - Provides information about which branch is being rebased and where the conflict occurred\n   - May create automatic backup branches if conflicts are detected\n\n2. **Resolution Process**:\n   - The conflicted files will be marked with conflict markers (`\u003c\u003c\u003c\u003c\u003c\u003c\u003c`, `=======`, `\u003e\u003e\u003e\u003e\u003e\u003e\u003e`)\n   - Resolve conflicts manually by editing the conflicted files\n   - Add the resolved files with `git add \u003cfile\u003e`\n   - Continue the rebase with `git rebase --continue`\n\n3. **Continuing After Resolution**:\n   - After resolving the conflicts and continuing the rebase for the current branch, you can resume updating the chain:\n   ```\n   git chain rebase\n   ```\n   - Git Chain will pick up where it left off, continuing with the remaining branches\n\n4. **Aborting a Problematic Rebase**:\n   - If you decide not to resolve the conflicts, you can abort the current rebase:\n   ```\n   git rebase --abort\n   ```\n   - Then, if you created backup branches, you can restore from them:\n   ```\n   git checkout branch-name\n   git reset --hard branch-name-backup\n   ```\n\n**Example Conflict Workflow**:\n```\n$ git chain rebase\nRebasing branch feature/auth onto master...\nAuto-merging src/auth.js\nCONFLICT (content): Merge conflict in src/auth.js\nerror: could not apply 1a2b3c4... Add authentication feature\n\n# Resolve the conflict\n$ vim src/auth.js\n$ git add src/auth.js\n$ git rebase --continue\nSuccessfully rebased branch feature/auth\n\nRebasing branch feature/profiles onto feature/auth...\n# Continues with remaining branches\n```\n\n### Recovery Options\n\nIf a rebase goes wrong, Git Chain provides several recovery options:\n\n1. **Backup Branches**: If you used `--backup`, you can restore using:\n   ```\n   git checkout branch-name\n   git reset --hard branch-name-backup\n   ```\n\n2. **Reflog**: Even without backups, you can recover using Git's reflog:\n   ```\n   git checkout branch-name\n   git reflog\n   git reset --hard branch-name@{1}  # Reset to previous state\n   ```\n\n3. **Abort In-Progress Rebase**: If a rebase is still in progress:\n   ```\n   git rebase --abort\n   ```\n\n## Merge Strategy: Preserving Branch History\n\n### Basic Concept\n\nWhen you run `git chain merge`, git-chain cascades merges through your branch chain by merging each parent branch into its child branch. Unlike rebasing, merging preserves the original commit history by creating merge commits that link branches together.\n\n### How It Works\n\n1. **Order Matters**: Branches are updated in the order they appear in the chain, starting from the one closest to the root branch. Each branch incorporates changes from its parent through a merge.\n\n2. **Finding the Right Starting Point**: Git Chain uses the same intelligent fork-point detection as in rebasing to identify the best common ancestor for each merge.\n\n3. **Smart Detection**: Git Chain checks for special cases:\n   - If branches can be fast-forwarded (no merge needed)\n   - If a branch has been squash-merged (to avoid duplicate changes)\n   - If there are merge conflicts that need manual resolution\n\n4. **The Actual Merging**: For each branch, git-chain runs a command similar to:\n   ```\n   git checkout \u003cbranch\u003e\n   git merge \u003cparent_branch\u003e\n   ```\n   This incorporates all changes from the parent branch while preserving the branch's original commit history.\n\n### Command Options and Flags\n\nGit Chain's merge command offers extensive customization through various flags and options:\n\n#### Basic Options\n\n- **`--verbose, -v`**: Provides detailed output during the merging process\n  ```\n  git chain merge --verbose\n  ```\n  Shows exactly what's happening with each branch, including Git's merge output.\n\n- **`--ignore-root, -i`**: Skips merging the root branch into the first branch\n  ```\n  git chain merge --ignore-root\n  ```\n  Useful when you want to update relationships between branches in the chain without incorporating root branch changes.\n\n- **`--stay`**: Don't return to the original branch after merging\n  ```\n  git chain merge --stay\n  ```\n  By default, git-chain returns you to your starting branch. Use this flag to remain on the last merged branch.\n\n- **`--chain=\u003cname\u003e`**: Operate on a specific chain other than the current one\n  ```\n  git chain merge --chain=feature-x\n  ```\n  Allows you to merge a chain even when you're not on a branch that belongs to it.\n\n#### Merge Behavior Controls\n\n- **`--simple, -s`**: Use simple merge mode without advanced detection\n  ```\n  git chain merge --simple\n  ```\n  Disables fork-point detection and squashed merge handling for a faster, simpler merge process.\n\n- **`--fork-point, -f`**: Use Git's fork-point detection (default behavior)\n  ```\n  git chain merge --fork-point\n  ```\n  Explicitly enables fork-point detection for finding better merge bases.\n\n- **`--no-fork-point`**: Disable fork-point detection, use regular merge-base\n  ```\n  git chain merge --no-fork-point\n  ```\n  Can be faster but potentially less accurate. Useful for repositories with limited reflog history.\n\n- **`--squashed-merge=\u003cmode\u003e`**: How to handle branches that appear squash-merged\n  ```\n  git chain merge --squashed-merge=reset  # Default: reset to match parent branch\n  git chain merge --squashed-merge=skip   # Skip branches that appear squashed\n  git chain merge --squashed-merge=merge  # Force merge despite the detection\n  ```\n  Controls behavior when Git Chain detects that a branch appears to have been squash-merged into its parent.\n\n#### Git Merge Options\n\n- **Fast-forward behavior**:\n  ```\n  git chain merge --ff        # Allow fast-forward if possible (default)\n  git chain merge --no-ff     # Always create a merge commit\n  git chain merge --ff-only   # Only allow fast-forward merges\n  ```\n  Controls how Git handles cases where a branch can be fast-forwarded.\n\n- **`--squash`**: Create a single commit instead of a merge commit\n  ```\n  git chain merge --squash\n  ```\n  Combines all changes from the source branch into a single commit.\n\n- **`--strategy=\u003cstrategy\u003e`**: Use a specific Git merge strategy\n  ```\n  git chain merge --strategy=recursive\n  git chain merge --strategy=ours\n  ```\n  Specifies which Git merge strategy to use (e.g., recursive, resolve, octopus).\n\n- **`--strategy-option=\u003coption\u003e`**: Pass strategy-specific options\n  ```\n  git chain merge --strategy=recursive --strategy-option=ignore-space-change\n  git chain merge --strategy=recursive --strategy-option=patience\n  ```\n  Customizes the behavior of the selected merge strategy.\n\n#### Reporting Options\n\n- **Adjusting report detail**:\n  ```\n  git chain merge --report-level=minimal    # Basic success/failure messages\n  git chain merge --report-level=standard   # Summary with counts (default)\n  git chain merge --report-level=detailed   # Comprehensive per-branch details\n  git chain merge --no-report               # Suppress merge summary report\n  git chain merge --detailed-report         # Same as --report-level=detailed\n  ```\n  Controls how much information is displayed after the merge completes.\n\n### Examples (`git chain merge`)\n\nHere are some common scenarios and how to handle them with git-chain merge:\n\n#### 1. Updating PRs without breaking review comments\n\n**Scenario**: You have multiple PRs open, and the main branch has received changes.\n\n**Solution**:\n```\ngit chain merge\n```\nThis preserves all original commits while incorporating upstream changes via merge commits.\n\n#### 2. Custom merge handling for a specific chain\n\n**Scenario**: You want to update a feature chain while on an unrelated branch.\n\n**Solution**:\n```\ngit chain merge --chain=feature-login --verbose\n```\nThis updates the specified chain with detailed output and returns you to your original branch when complete.\n\n#### 3. Clean merge history with no extra merge commits\n\n**Scenario**: You want to update the chain while maintaining a cleaner history where possible.\n\n**Solution**:\n```\ngit chain merge --ff-only\n```\nThis only updates branches that can be fast-forwarded, failing if a real merge would be required.\n\n#### 4. Simplified merge for branches with squashed history\n\n**Scenario**: Your workflow includes squash-merging branches, and you need to handle this intelligently.\n\n**Solution**:\n```\ngit chain merge --squashed-merge=skip\n```\nThis skips branches that appear to have been squash-merged, avoiding duplicate changes.\n\n#### 5. Focused merge excluding root changes\n\n**Scenario**: You want to merge changes between branches in the chain but not from the root branch.\n\n**Solution**:\n```\ngit chain merge --ignore-root\n```\nThis skips merging the root branch into the first chain branch.\n\n#### 6. Complex conflict resolution with detailed reporting\n\n**Scenario**: You anticipate merge conflicts and want clear information to resolve them.\n\n**Solution**:\n```\ngit chain merge --verbose --detailed-report\n```\nThis provides maximum information during the merge process and in the final report.\n\n### Handling Merge Conflicts\n\nWhen merging branches in a chain, conflicts can sometimes occur. Git Chain handles conflicts as follows:\n\n1. **Conflict Detection**: When a merge conflict occurs, git-chain:\n   - Stops the merging process at the conflicted branch\n   - Leaves the repository in a conflicted state for you to resolve\n   - Provides information about which branches conflicted\n   - Shows which files have conflicts\n\n2. **Resolution Process**:\n   - The conflicted files will be marked with conflict markers (`\u003c\u003c\u003c\u003c\u003c\u003c\u003c`, `=======`, `\u003e\u003e\u003e\u003e\u003e\u003e\u003e`)\n   - Resolve conflicts manually by editing the conflicted files\n   - Add the resolved files with `git add \u003cfile\u003e`\n   - Complete the merge with `git commit`\n\n3. **Continuing After Resolution**:\n   - After resolving the conflicts and committing the merge, you can continue updating the chain:\n   ```\n   git chain merge\n   ```\n   - Git Chain will pick up where it left off, continuing with the remaining branches\n\n**Example Conflict Output**:\n```\nProcessing branch: feature/auth\nAuto-merging src/config.js\nMerge made by the 'recursive' strategy.\n src/config.js | 10 ++++++++++\n 1 file changed, 10 insertions(+)\n\nProcessing branch: feature/profiles\n🛑 Merge conflict between feature/auth and feature/profiles:\nAuto-merging src/models/user.js\nCONFLICT (content): Merge conflict in src/models/user.js\nAutomatic merge failed; fix conflicts and then commit the result.\n\nerror: Merge conflict between feature/auth and feature/profiles\n\n📊 Merge Summary for Chain: feature\n  ✅ Successful merges: 1\n  ⚠️  Merge conflicts: 1\n     - feature/auth into feature/profiles\n  \n⚠️  Chain feature was partially merged with conflicts.\n   Run `git status` to see conflicted files.\n   After resolving conflicts, continue with regular git commands:\n     git add \u003cresolved-files\u003e\n     git commit -m \"Merge conflict resolution\"\n```\n\n### When to Use Merge vs. Rebase\n\n- **Use Merge When**:\n  - You're working with branches that already have open pull/merge requests\n  - You want to preserve the complete history of branch development\n  - You need to maintain the context of review comments on specific commits\n  - You're collaborating with others who are also working on the branches\n\n- **Use Rebase When**:\n  - You're working on private branches that haven't been shared\n  - You prefer a linear, cleaner history\n  - You want each branch's changes to appear as if they were developed on top of the latest version of their parent\n\n## Installation\n\n1. Install Rust and Cargo: https://rustup.rs\n2. Get the Git Chain code:\n   ```\n   git clone https://github.com/evansst/git-chain.git\n   cd git-chain\n   ```\n3. Build the tool:\n   ```\n   make build\n   ```\n4. Make it available on your system:\n   ```\n   cp target/release/git-chain /usr/local/bin/\n   ```\n\nThis allows you to use the tool with:\n```\ngit chain \u003ccommand\u003e\n```\n\nAlternatively, you can create a Git alias:\n```\ngit config --global alias.chain \"!/path/to/target/release/git-chain\"\n```\n\n## Getting Started: A Simple Example\n\nLet's see how to use Git Chain with a simple example:\n\n### 1. Set up a chain\n\nAssuming you have branches `feature-1` and `feature-2` that are stacked:\n\n```\ngit chain setup my-feature master feature-1 feature-2\n```\n\nThis creates a chain named \"my-feature\" with `master` as the root branch and the branches arranged in order.\n\n### 2. Rebase the entire chain\n\nWhen you need to update the chain (after new commits on `master` or any branch in the chain):\n\n```\ngit checkout feature-2  # You can be on any branch in the chain\ngit chain rebase\n```\n\nGit Chain will:\n- Find all the branches in the chain\n- Determine the correct rebase order\n- Rebase each branch on top of its parent\n\n### 3. View your current chain\n\nTo see information about the current chain:\n\n```\ngit chain\n```\n\nThis displays the chain structure and shows the relationship between branches.\n\n## Core Commands\n\n### Creating and Managing Chains\n\n```\n# Set up a new chain with multiple branches\ngit chain setup \u003cchain_name\u003e \u003croot_branch\u003e \u003cbranch_1\u003e \u003cbranch_2\u003e ... \u003cbranch_N\u003e\n\n# Add the current branch to a chain (in the last position)\ngit chain init \u003cchain_name\u003e \u003croot_branch\u003e\n\n# Add the current branch with specific positioning\ngit chain init \u003cchain_name\u003e \u003croot_branch\u003e --before=\u003cother_branch\u003e\ngit chain init \u003cchain_name\u003e \u003croot_branch\u003e --after=\u003cother_branch\u003e\ngit chain init \u003cchain_name\u003e \u003croot_branch\u003e --first\n\n# Move a branch within its chain\ngit chain move --before=\u003cother_branch\u003e\ngit chain move --after=\u003cother_branch\u003e\ngit chain move --chain=\u003cchain_name\u003e\n\n# Rename a chain\ngit chain rename \u003cnew_chain_name\u003e\n```\n\n### Viewing Chain Information\n\n```\n# Display the current chain (if the current branch is part of one)\ngit chain\n\n# List all chains in the repository\ngit chain list\n```\n\n### Working with Chains\n\n```\n# Rebase all branches in the current chain (rewrites history)\ngit chain rebase\n\n# Rebase one branch at a time\ngit chain rebase --step\n\n# Skip rebasing the first branch onto the root branch\ngit chain rebase --ignore-root\n\n# Merge all branches in the current chain (preserves history)\ngit chain merge\n\n# Merge with detailed output\ngit chain merge --verbose\n\n# Skip merging the root branch into the first branch\ngit chain merge --ignore-root\n\n# Create merge commits even for fast-forward merges\ngit chain merge --no-ff\n\n# Only allow fast-forward merges\ngit chain merge --ff-only\n\n# Use simple merge mode (without advanced detection)\ngit chain merge --simple\n\n# Specify how to handle squashed merges\ngit chain merge --squashed-merge=reset  # Reset branch to parent (default)\ngit chain merge --squashed-merge=skip   # Skip branches that appear squashed\ngit chain merge --squashed-merge=merge  # Merge despite squashed detection\n\n# Set the level of detail in the merge report\ngit chain merge --report-level=minimal    # Basic success/failure only\ngit chain merge --report-level=standard   # Summary with counts (default)\ngit chain merge --report-level=detailed   # Comprehensive per-branch details\ngit chain merge --no-report               # Suppress report entirely\ngit chain merge --detailed-report         # Same as --report-level=detailed\n\n# Don't return to original branch after merging\ngit chain merge --stay\n\n# Merge a different chain than the current one\ngit chain merge --chain=feature-login\n\n# Use specific Git merge strategy and options\ngit chain merge --strategy=recursive --strategy-option=ignore-space-change\n\n# Create backup branches for all branches in the chain\ngit chain backup\n\n# Push all branches in the chain to their upstreams\ngit chain push\ngit chain push --force  # Use --force-with-lease\n\n# Navigate between branches in the chain\ngit chain first  # Switch to the first branch in the chain\ngit chain last   # Switch to the last branch in the chain\ngit chain next   # Switch to the next branch in the chain\ngit chain prev   # Switch to the previous branch in the chain\n\n# Prune branches that have been merged to the root branch\ngit chain prune\n```\n\n### Removing Branches from Chains\n\n```\n# Remove the current branch from its chain\ngit chain remove\n\n# Remove the entire chain \ngit chain remove --chain\n\n# Remove a specific chain\ngit chain remove --chain=\u003cchain_name\u003e\n```\n\n## Smart Branch Management Features\n\nGit Chain has several advanced features:\n\n- **Multiple update strategies**: Choose between rebasing (rewriting history) or merging (preserving history)\n- **Fork-point detection**: Uses Git's fork-point detection to find the correct base for rebases and merges\n- **Squash-merge detection**: Can detect when a branch has been squash-merged into its parent\n- **Detailed reporting**: Provides clear summaries of operations performed on your branches\n- **Backup branches**: Creates backup branches before rebasing to safeguard your work\n- **Branch navigation**: Easily move between branches in your chain\n- **Chain reorganization**: Move branches around within the chain or between chains\n\n## ⚠️ Important Limitations ⚠️\n\nGit Chain does not:\n\n1. Create or delete branches for you. You still need to use standard Git commands for these operations.\n\n2. Make assumptions about your branching intent. It only works with the chain structure you explicitly define.\n\n## Similar Tools\n\nThis tool was inspired by [Shopify/git-chain](https://github.com/Shopify/git-chain).\n\nIf you need more features, check out these alternatives:\n- [git-stack](https://github.com/epage/git-stack)\n- [gh-stack](https://github.com/timothyandrew/gh-stack)\n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdashed%2Fgit-chain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdashed%2Fgit-chain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdashed%2Fgit-chain/lists"}