Skip to content

Repository files navigation

Kindra

Kindra is a CLI tool for managing stacked git branches. Its kin command automates the tedious parts of working with dependent branches, such as rebasing descendants after a commit or moving an entire stack of work to a new base.

Key Features

  • Stacked Commits: Automatically rebase all descendant branches when you commit in the middle of a stack.

  • Stack-Aware Absorb: Distribute staged changes into the commits that introduced the touched lines (via the git-absorb engine), fold them, and restack descendants in one pass.

  • Atomic Stack Moves: Move a branch and all its descendants onto a new base branch in one pass using --update-refs.

  • Fork-Aware Reordering: Edit branch parent relationships in your $EDITOR, including creating or preserving forks.

  • Smart Sync: Rebase the current stack onto main/master in one pass using --update-refs, while skipping already-landed lower PRs.

  • Auto-Restack: Automatically identify and repair "floating" branches that were based on an old version of the current branch (e.g., after an amend or rebase).

  • Interactive Navigation: Quickly hop between branches in your stack with up, down, and top commands.

  • Visual Branch Splitting: Assign branches to specific commits in a linear history using your favorite $EDITOR.

  • Atomic Pushes: Push all branches in your stack simultaneously with force-with-lease safety.

  • Run Commands Across Stack: Execute shell commands on each branch in your stack with kin run.

  • PR Workflow Helpers: Create/update stack PRs with automatic flatten/push preflight, flatten stack PR bases to upstream, open PRs in your browser, edit PR metadata, inspect review/check status, export threaded review comments as markdown, and merge stack PRs with readiness checks — retargeting child PR bases on GitHub so they aren't orphaned by the merge, then (unless --no-cascade) restacking children onto the updated trunk and deleting the merged branch locally and on the remote (--method squash|rebase|merge, --no-cascade, --no-delete).

Installation

Kindra can be installed directly from GitHub:

cargo install --git https://github.com/Pajn/kindra.git kindra --bin kin

If you already use cargo-binstall, the git-based install works there too:

cargo binstall --git https://github.com/Pajn/kindra.git kindra

You can also install it from source:

# Clone the repository
git clone https://github.com/Pajn/kindra.git
cd kindra

# Build and install
cargo install --path .

Releasing

Kindra uses cargo-release to keep the Cargo version, version bump commit, and Git tag in sync. The GitHub release workflow runs when a v* tag is pushed.

cargo install cargo-release

# Review the planned version bump, commit, tag, and push.
cargo release 0.3.0

# Perform the release after reviewing the dry run.
cargo release 0.3.0 --execute

Quick Start

  1. Start a stack: Create several branches, each building on the previous one — with plain git checkout -b, or kin commit -b <name> to fork a branch and commit onto it in one step (add --insert to splice it into the middle of an existing stack).
  2. Make a change: Checkout a branch in the middle of the stack and run kin commit.
  3. Watch the magic: Kindra will automatically rebase all branches that depend on your change.
  4. Move the stack: Ready to target a different feature? kin move --onto main to relocate the entire stack.
  5. Sync after merges: If lower PRs landed, run kin sync to rebase the remaining stack onto latest main.
  6. Reorder the stack: Need to reshuffle or fork branches? Run kin reorder and edit the parent map in your editor.
  7. Repair broken stacks: Amended a commit and left dependent branches "floating"? Run kin restack to fix them.
  8. Manage PRs in stack:
    • kin pr to create/update your PRs, automatically flattening mismatched PR bases and pushing first
    • kin pr --all to include PRs in the stack that are authored by other GitHub users
    • kin pr --no-push to skip that preflight and use the old create/update behavior
    • kin pr open to open a PR from the stack
    • kin pr edit to edit title/body/labels/reviewers
    • kin pr flatten to retarget all open stack PRs to the resolved upstream base branch on GitHub
    • kin pr status to inspect reviewers, unresolved comments, and failing/running checks
    • kin pr review to render PR review threads as markdown, optionally write them to a file, or copy them via OSC 52
    • kin pr merge to merge a stack PR only when reviews/checks are ready, or clearly explain/prompt when GitHub would still allow an override
  9. Run across stack: kin run -c "cargo test" to run tests on each branch in the stack.
  10. Undo a mistake: Didn't like the result of a sync, reorder, move, restack, or split? Run kin undo to restore the previous branch tips (and kin redo to reapply, or kin reflog to review recent operations).

For a full list of commands and detailed examples, see the CLI Reference.

kin reorder editor format

kin reorder opens a file with one row per branch:

branch feature-c parent main
branch feature-a
branch feature-b
  • branch <name> parent <parent> sets the branch parent explicitly.
  • branch <name> means "make the branch on the previous line the parent".
  • The first row must have an explicit parent, usually your upstream branch.
  • Forks are created by repeating the same explicit parent on multiple rows.

Example fork:

branch feature-c parent main
branch feature-a parent feature-c
branch feature-b parent feature-c

Upstream Branch Selection

Commands that need an upstream/base branch (for example sync, split, push, commit, and move) resolve it in this order:

  1. Repository override in .git/kindra.toml:

    upstream_branch = "branch-name"
  2. git config init.defaultBranch

  3. Built-in defaults: main, master, trunk

  4. Remote fallbacks: origin/<branch>

Managed Worktrees

Kindra now includes an opinionated kin wt workflow for managed git worktrees:

  • kin wt main ensures a stable trunk worktree exists.
  • kin wt review [branch] creates or reuses a fixed review worktree and repoints it safely.
  • kin wt temp [branch] creates or reuses a branch-scoped disposable worktree, and kin wt temp -b <new-branch> [start-point] creates a new branch in one.
  • kin wt add [branch] creates (or reuses) a durable worktree for a branch in a sibling directory, or in <repo>/worktrees/{branch} when the repository has no parent directory, and kin wt add -b <new-branch> [start-point] creates a new branch in one. Unlike temp, added worktrees are never auto-cleaned.
  • kin wt list shows every git worktree and its current state (role, or - for plain worktrees).
  • kin wt path <target> prints just the worktree path for shell/editor integrations.
  • kin wt cd <target> changes directory into a worktree (needs shell integration — see below).
  • kin shell-init <bash|zsh|fish> (top-level) prints the shell snippet that enables kin wt cd.
  • kin wt remove <target> removes a worktree (by role or branch) with confirmation by default.
  • kin wt cleanup removes merged Kindra-managed temp worktrees.

By default Kindra stores the role worktrees (main/review/temp) under:

.git/kindra-worktrees/

That keeps disposable working trees out of the repo root while still making them easy to find and clean up. Durable kin wt add worktrees instead default to a sibling directory (../<repo>-worktrees/{branch}), or to <repo>/worktrees/{branch} when the repository has no parent directory, so they're visible to editors and git status.

Examples

# Ensure a persistent trunk worktree exists
kin wt main

# Reuse a stable review workspace for the current branch
kin wt review

# Switch the review workspace to another branch
kin wt review feature/auth

# Create or reuse a temp worktree for a branch
kin wt temp feature/auth

# Create a new temp worktree branch from the current branch
kin wt temp -b feature/spike

# Create a new temp worktree branch from origin/main
kin wt temp -b hotfix/main origin/main

# Create a durable sibling worktree for a branch you want to keep checked out
kin wt add feature/auth

# Use the resolved path in shell tooling
cd "$(kin wt path review)"

# Or, with shell integration enabled, cd straight into a worktree
kin wt cd feature/auth

# Remove a single managed temp worktree
kin wt remove feature/auth

# Clean up merged temp worktrees
kin wt cleanup

Shell integration (kin wt cd)

kin wt cd <target> moves your shell into a worktree. Because a CLI process can't change its parent shell's directory, this needs a one-time wrapper (from the top-level kin shell-init) in your shell config:

# bash / zsh
eval "$(kin shell-init zsh)"
# fish
kin shell-init fish | source

The wrapper intercepts kin wt cd and forwards everything else straight to kin. Without it, kin wt cd just prints the path (and tells you how to enable the integration).

kin shell-init also registers Kindra's shell completions by default, so that one line sets up both. Pass --no-completions if you install completions separately.

Worktree config

Managed worktrees use repo-local config in .git/kindra.toml:

[worktrees]
trunk = "main"
# Default location for `kin wt add` ({branch} required; sibling dir by default,
# falling back to <repo>/worktrees when the repo has no parent directory).
add_path_template = "../myrepo-worktrees/{branch}"

[worktrees.hooks]
on_create = []
on_checkout = []
on_remove = []

[worktrees.main]
path = ".git/kindra-worktrees/main"

[worktrees.review]
path = ".git/kindra-worktrees/review"

[worktrees.temp]
path_template = ".git/kindra-worktrees/temp/{branch}"
delete_merged = true

Notes:

  • main is pinned to the configured trunk branch.
  • review reuses a fixed path and refuses to discard local changes unless you confirm or pass --force.
  • add worktrees default to add_path_template; by default that is a sibling directory, or <repo>/worktrees/{branch} when the repo has no parent directory. Pass --path to override. Unlike the role paths it isn't required to live under the managed root.
  • cleanup only targets Kindra-managed temp worktrees, never main, review, or plain/added worktrees.
  • kin wt path is the script-friendly command: it prints only the resolved path on success.
  • Use branch:<name> with kin wt path or kin wt remove to target a branch literally named main or review.
  • Hooks run in the worktree directory and stop the action if they fail. kin wt add runs only the global [worktrees.hooks]; role worktrees run global plus role-specific hooks.

Restack History Limit

kin restack bounds floating-branch discovery by default so very deep repositories do not pay for an unbounded first-parent scan.

Resolution order:

  1. CLI override: kin restack --history-limit <n>
  2. Repository config in .git/kindra.toml
  3. Global config in the standard platform config directory as kindra/config.toml
  4. Built-in default: 100

Use 0 to disable the bound and scan the full first-parent history.

Example repository config:

[restack]
history_limit = 250

Rebase Autostash

Commands that start a Git rebase (commit, move, sync, and restack) default to --no-autostash so dirty tracked changes do not get hidden implicitly.

Resolution order:

  1. CLI override: --autostash or --no-autostash
  2. Repository config in .git/kindra.toml
  3. Global config in the standard platform config directory as kindra/config.toml
  4. Built-in default: false

Example config:

[rebase]
autostash = true

Benchmarking

Run the permanent Criterion benchmarks for stack navigation (checkout top, co up, co down) across two repository shapes:

  • 5,000 commits on main + 10,000 noise branches
  • 50,000 commits on main + 1,000 noise branches
cargo bench --bench checkout_top

Why Kindra?

Traditional git workflows often involve large, monolithic Pull Requests or manual, error-prone rebasing when trying to keep multiple small, dependent PRs in sync. Kindra treats your branches as a stack, allowing you to focus on small, reviewable increments of code while it handles the plumbing.

About

CLI for working with PR stacks with pure git

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages