🔗 Tool for rebasing a chain of local git branches.

Overview

git-chain

Tool for rebasing a chain of local git branches.

Motivation

Suppose you have branches, each depending on a parent branch (usually called "stacked branches"):

                            I---J---K  feature-2
                           /
                  E---F---G  feature-1
                 /
    A---B---C---D  master

Pulling in new changes on the master branch, and then rebasing feature-1 and feature-2 on top of master can be tedious to do.

With git-chain, you can automate the rebasing steps by setting up the chain feature-1 and feature-2 with master as the root branch:

  1. git chain setup big-feature master feature-1 feature-2
  2. git checkout feature-2 (switch into any branch of the big-feature chain)
  3. git chain rebase

git-chain can also rebase all the branches of the chain if you add commits in any branch in the chain:

                            J---K---L  feature-2
                           /
                  E---F---G---H---I  feature-1
                 /
    A---B---C---D  master

This tool was built to solve the following Stack Overflow question: https://stackoverflow.com/q/20834648/412627

Concepts

A chain (or a "git chain") consists of the root branch, and branches that branch off of other branches containing incremental changes of a large feature.

The root branch is the branch of which the chain of branches will merge into. Typically the root branch is master or main.

The "chain" as defined can also be called "stacked branches" in other tools. See below.

Note:

  • A branch can be part of at most one chain.
  • The root branch is not part of the chain.

Rebase strategy

git chain will rebase branches of the chain in the order that they are defined. For each branch, a fork-point is generated with git merge-base --fork-point between the branch and the branch's parent (its dependency). The parent of the first branch of the chain is the root branch.

The rebase is applied in the following way for each branch:

fork_point=$(git merge-base --fork-point $parent_branch $branch)
git rebase --onto $parent_branch $fork_point $branch

The fork-points are generated for each branch before rebasing.

To read more about fork-point, see: https://git-scm.com/docs/git-merge-base#_discussion_on_fork_point_mode

⚠ī¸ ⚠ī¸ ⚠ī¸ What this tool does not do

  1. This tool will not create, nor destroy branches for you. You should use git branch (or other commands) for that.

  2. This tool doesn't attempt to be smart, or make assumptions of what your branching intent looks like. It only understands the chain that you have set up.

Installation

  1. Install cargo and rust: https://rustup.rs
  2. Checkout this repository and run cargo build --release
  3. Copy target/release/git-chain to your path. (e.g. cp target/release/git-chain /usr/local/bin/)

Usage

# Set up a new chain.
git chain setup <chain_name> <root_branch> <branch_1> <branch_2> ... <branch_N>

# Add current branch to a chain into the last position.
git chain init <chain_name> <root_branch>
# Example:
git chain init super_big_feature master

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

# Display current chain.
git chain

# List all chains.
git chain list

# Back up all branches of the current chain.
# For each branch in the current chain, create new branch with the name: backup-<chain_name>/<branch>
# If the backup branch already exists, then it is replaced.
git chain backup

# Rebase all branches on the chain.
git chain rebase
# Run at most one rebase that will perform a history rewrite.
git chain rebase --step

# Push all branches on the current chain to their upstreams.
# Note: this is not a force push!
git chain push
# Push branches with --force-with-lease
git chain push --force

# Prune any branches of the current chain that are ancestors of the root branch.
git chain prune

# Remove current branch from any chain.
git chain remove

# Remove current branch and the chain it is a part of.
git chain remove --chain

# Remove chain by name.
git chain remove --chain=<chain_name>

# Move the current branch.
git chain move --before=<other_branch>
git chain move --after=<other_branch>
git chain move --chain=<chain_name>
git chain move --chain=<chain_name> --before=<other_branch>
git chain move --chain=<chain_name> --after=<other_branch>

# Update the root branch of the chain the current branch is a part of.
git chain move --root=<root_branch>

# Rename current chain.
git chain rename <chain_name>

# Switching between branches on the current chain.
git chain first
git chain last
git chain next
git chain prev

Other tools

This tool is largely inspired by Shopify/git-chain. In fact, I initially used this tool first, before writing my own version.

You may be interested in exploring these tools that have a richer feature set than git chain:

License

MIT.

You might also like...
EVM compatible chain with NPoS/PoC consensus

Reef Chain Reef chain is written in Rust. A basic familiarity with Rust tooling is required. To learn more about Reef chain, please refer to Documenta

Basilisk node - cross-chain liquidity protocol built on Substrate

Basilisk node Local Development Follow these steps to prepare a local Substrate development environment 🛠ī¸ Simple Setup Install all the required depe

The Solana Program Library (SPL) is a collection of on-chain programs targeting the Sealevel parallel runtime.

Solana Program Library The Solana Program Library (SPL) is a collection of on-chain programs targeting the Sealevel parallel runtime. These programs a

Examples of Solana on-chain programs

spl-examples List of Solana on-chain programs which demonstrate different aspects of Solana architecture. 01__state It's a counter program. Each user

Synchronized shadow state of Solana programs available for off-chain processing.

Solana Shadow The Solana Shadow crate adds shadows to solana on-chain accounts for off-chain processing. This create synchronises all accounts and the

Making composability with the Zeta DEX a breeze, FuZe provides CPI interfaces and sample implementations for on-chain program integration.
Making composability with the Zeta DEX a breeze, FuZe provides CPI interfaces and sample implementations for on-chain program integration.

Zeta FuZe đŸ§Ŧ Zeta FuZe FuZe is Zeta's cross-program integration ecosystem. This repository contains the Zeta Cross Program Invocation (CPI) interface

Extremely low-latency chain data to Stackers, with a dose of mild humour on the side
Extremely low-latency chain data to Stackers, with a dose of mild humour on the side

Ronin Hello there! Ronin is a ultra-speed Stacks API server. It's super lightweight, but scales easily. Why are we making this? Because we don't like

A collection of Solana-maintained on-chain programs

Solana Program Library The Solana Program Library (SPL) is a collection of on-chain programs targeting the Sealevel parallel runtime. These programs a

The protocol are designed and made for the future of cross-IP, cross-chain metaverse.

Avatar-protocol 化čēĢåčŽŽ This project demonstrates how to use the Solana Javascript API to interact with programs on the Solana blockchain. The project co

Comments
  • Detect branches that were squashed and merged to upstream branches

    Detect branches that were squashed and merged to upstream branches

    Be able to detect branches that were squashed and merged to upstream branches when rebasing the chain.

    See example: https://news.ycombinator.com/item?id=29257812

    opened by dashed 1
  • Improve

    Improve "Unable to get forkpoint" error message

    This error message isn't very useful, and the user will get stuck not knowing what the next steps are:

    sentry (jferg/scim-doc-6):$ git chain rebase
    error: Unable to get forkpoint of jferg/scim-doc-2 and jferg/scim-doc-3
    

    It'll be helpful to provide some suggestions.

    opened by dashed 0
  • git chain push should set upstream automatically if one does not exist

    git chain push should set upstream automatically if one does not exist

    git chain push should set upstream (remote) automatically if one does not exist. This is more smarter than bailing out naively:

    https://github.com/dashed/git-chain/blob/f51494ccae51b948051435362efcdfb6a530bed7/src/main.rs#L340-L347

    Do not do this for git chain push --force since it's a dangerous operation.

    Bonus: if git chain push --force fails, then suggest that the user run git chain push if upstream (remote) branches are detected to not be set.


    Starting points:

    • https://docs.rs/git2/latest/git2/struct.Repository.html#method.remotes
    • https://docs.rs/git2/0.13.25/git2/struct.Branch.html#method.set_upstream
    • https://docs.rs/git2/0.13.25/git2/struct.Branch.html#method.set_upstream
    opened by dashed 0
Owner
Alberto Leal
🇨đŸ‡Ļ he/him/his
Alberto Leal
Sothis is a tool for replaying historical state on a local testnet node.

sothis Sothis is a tool for replaying historical state on a local anvil/hardhat testnet node. Usage Sothis currently has 2 modes. Live and historic. I

null 22 Jun 15, 2023
Built for Perpetual Protocol v2 Curie on Optimism chain. This CLI tool was built with Rust.

Perpetual Protocol CLI for Perp v2 Curie This tool is to provide a simple, fast and efficient way to interact Perpetual Protocol contracts from your t

Brendan Wenzel 4 Jan 11, 2023
CLI tool for deterministically building and verifying executable against on-chain programs or buffer accounts

Solana Verify CLI A command line tool to build and verify solana programs. Users can ensure that the hash of the on-chain program matches the hash of

Ellipsis Labs 5 Jan 30, 2023
🗂ī¸ A simple, opinionated, tool, written in Rust, for declaratively managing Git repos on your machine.

gitrs ??ī¸ A simple, opinionated, tool, written in Rust, for declaretively managing Git repos on your machine. "simple" - limited in what it supports.

Colton J. McCurdy 14 May 30, 2023
Local blockchain for Free TON DApp development and testing.

TON OS Startup Edition Local blockchain for Free TON DApp development and testing. Have a question? Get quick help in our channel: TON OS Startup Edit

TON Labs 35 Jan 2, 2023
An Ethereum 2.0 Emulator for Local Testing of Eth2 Applications

Mousse is an Ethereum 2.0 emulator for local testing of Eth2 applications (mainly Rollups). HTTP Server The REST API definition can be found in the ht

Mousse 46 Sep 10, 2022
Figures out the local timezone as IANA / Olson identifier

localzone Utility crate to figure out the IANA (Olson) timezone of the current machine. The IANA timezones have been largely established as the standa

Armin Ronacher 11 Jan 4, 2022
Unified directories for different use cases of an application, providing standard directories for local development, when run as service or when run by a user.

UniDirs Unified directories for different use cases of an application, providing standard directories for local development, when run as service or wh

Dominik Nakamura 3 Sep 30, 2022
Cross-chain hub for Crypto Asset on Polkadot

ChainX ChainX is a community-driven project built on the next-generation blockchain framework substrate, the largest Layer-2 network of Bitcoin using

ChainX 261 Dec 28, 2022
Official implementation of the YeeCo Root Chain (Layer 1)

yeeroot Official implementation of the YeeCo Root Chain (Layer 1) YeeCo is a permissionless, secure, high performance and scalable public blockchain p

YeeCo 29 Sep 20, 2022