Skip to content

chmouel/git-branches

Repository files navigation

git-branches

PyPI - Version Python 3.12+ Code style: ruff Pre-commit License: Apache-2.0

An interactive Git branch browser powered by fzf, with rich previews for GitHub PRs and CI status. It’s fast, keyboard-first, and designed for day-to-day workflows: jump to branches, spin up local tracking from remotes, open the PR in your browser, or prune branches in bulk.

image

🍺 Homebrew CI: Homebrew CI

TL;DR ⚡️

# Install (Homebrew tap)
brew tap chmouel/git-branches https://github.com/chmouel/git-branches
brew install --HEAD chmouel/git-branches/git-branches

# Browse local branches (preview on top)
git-branches

# Browse remote branches (pick a remote)
git-branches -r

# Show pushed-status icons for local branches
git-branches -s   # add -S to show all

# Show GitHub Actions status (fetch over network)
git-branches --checks

# Current status with unpushed changes and PR info
git-branches --status

# Custom JIRA pattern and base branch
git-branches --jira-pattern "PROJ-\d+" --base-branch develop

# Super fast offline mode (no network, cached data only)
git-branches --fast

Highlights

  • fzf-native UX: reverse list, previews, key bindings, multi-select for deletes.
  • Rich preview: PR status (Open/Draft/Merged/Closed), OSC-8 clickable links to PRs, CI combined status, and the last 10 commits with colors.
  • Clickable terminal links: Branch names, PR numbers, JIRA tickets, and URLs are clickable using OSC 8 escape sequences (supported by modern terminals).
  • JIRA integration: Automatically detect JIRA tickets in branch names and show ticket details using jayrah with optional gum formatting.
  • GitHub awareness: shows whether a local branch exists on the remote (-s) and the CI status for the PR head commit.
  • One-keystroke actions: checkout, open PR (ctrl-o), delete quickly (alt-k).

Requirements

  • git and fzf on PATH
  • Python 3.12+ (uv-managed)
  • Optional: GITHUB_TOKEN (improves rate limits and enables private repos)
  • Optional: a Nerd Font for icons (fallback text is still readable)
  • Optional: jayrah for JIRA ticket integration
  • Optional: gum for enhanced JIRA ticket formatting
  • Optional: gh GitHub CLI for enhanced PR information in previews

Installation 🍺

uv tool install git+https://github.com/chmouel/git-branches.git@main

Homebrew (Tap)

You can install via a Homebrew tap that ships a Formula for git-branches.

Option A — tap this repo directly (HEAD installs from the main branch):

brew tap chmouel/git-branches https://github.com/chmouel/git-branches
brew install --HEAD chmouel/git-branches/git-branches

Quickstart 🚀

  • Browse and checkout local branches:
    • git-branches
  • Browse remotes and checkout (creates tracking branch if needed):
    • git-branches -r (select remote interactively)
    • git-branches -R origin
  • Browse GitHub pull requests and act on them:
    • git-branches --prs (Enter=checkout, Alt-w=create worktree)
  • Deletion workflows:
    • git-branches -d (delete local; multi-select)
    • git-branches -D -R origin (delete remote)
  • See if local branches exist on the remote:
    • git-branches -s (shows pushed status with default limit of 10)
    • git-branches -s -S (disable default limit)

Pull Request Browser

git-branches --prs opens an fzf view of the repository's GitHub pull requests (requires a GitHub remote and the gh CLI). Use Enter to fetch-and-checkout a local branch via gh pr checkout, or Alt-w to create a dedicated worktree after the branch has been materialised. Titles are sanitised (non POSIX-friendly characters replaced by - and truncated to 60 characters) to produce stable branch and directory names; existing directories receive a numeric suffix. Worktrees are placed under GIT_BRANCHES_WORKTREE_BASEDIR / PM_BASEDIR when set, otherwise alongside the repository in a <repo>-worktrees directory.

By default only OPEN pull requests are shown. Use --pr-states <STATE...> (e.g. --pr-states OPEN MERGED) to include additional states, or pass ALL to display every cached PR state. Icons within the PR list highlight local context: means the branch already exists locally, and indicates that the branch lives in a worktree.

Command-line options 🧭

Core Options

  • -r: Browse remote branches (choose remote via fzf)
  • -R <remote>: Browse a specific remote (e.g., origin)
  • -d: Delete local branches (multi-select)
  • -D: Delete remote branches (multi-select)
  • -s: Show pushed status for local branches (GitHub API)
  • -n <N>: Limit to first N branches
  • -S: With -s, disable default limit (show all)
  • -C: Disable colors
  • -l: List-only mode (no checkout)
  • --fast: Super fast offline mode (no network calls, minimal processing)
  • --refresh: Force refresh of PR cache (ignore stale cache and ETag)
  • --checks: Fetch and show GitHub Actions status (preview and a small indicator in rows). Without this flag, cached results (if available) are still displayed, but no network calls are made for checks.
  • --worktree: Show only branches that have worktrees
  • --prs: Browse GitHub pull requests (Enter=checkout branch, Alt-w=create worktree with sanitized title)
  • --pr-states <STATE...>: Filter PR browser states (default: OPEN; use ALL to include every state)

Preview & Integration Options

  • --status: Show current git status and unpushed changes preview
  • --jira-pattern REGEX: Custom regex pattern for JIRA ticket detection (e.g., 'PROJ-\d+', default: 'SRVKP-\d+')
  • --jira-url URL: JIRA base URL for ticket links (default: https://issues.redhat.com)
  • --no-jira: Disable JIRA ticket integration in previews
  • --base-branch BRANCH: Base branch for comparisons (default: main)

Key bindings (fzf)

  • ctrl-o: Open the PR for the highlighted ref in the default browser
  • alt-k: Force-delete highlighted local branch (quick action)

Shell Completion 🔌

There are two ways to enable completion:

  • Built-in generator (recommended)
  • Static scripts under contrib/

Built-in (Click-based)

git-branches can emit completion scripts for Bash, Zsh, Fish, and PowerShell.

Quick enable in the current shell session:

eval "$(uv run git-branches completion --shell bash)"   # Bash
eval "$(uv run git-branches completion --shell zsh)"    # Zsh
uv run git-branches completion --shell fish | source     # Fish

Persistent enablement:

  • Bash: add eval "$(git-branches completion --shell bash)" to ~/.bashrc
  • Zsh: add eval "$(git-branches completion --shell zsh)" to ~/.zshrc
  • Fish: add git-branches completion --shell fish > ~/.config/fish/completions/git-branches.fish

Extras:

  • -R/--remote-name offers remote name completion from git remote.
  • --pr-states completes to OPEN, CLOSED, MERGED, or ALL.

Static scripts (contrib/)

If you prefer static files, use the scripts under contrib/:

  • Zsh: _git-branches
  • Bash: git-branches.bash
  • Fish: git-branches.fish

Follow the comments in each file for installation.

Arch Linux (PKGBUILD / AUR-style)

This repository includes a PKGBUILD under aur/ for a -git style package (builds from HEAD).

  • Build locally with makepkg (requires base-devel):
cd aur
makepkg -sci --noconfirm

How it works

  • Uses git for data (branch lists, recent commits) and fzf for the UI.
  • Detects GitHub repository from the upstream of the current branch when possible, falling back to origin or the first remote.
  • For -s and preview CI status, calls the GitHub API with Authorization: Bearer $GITHUB_TOKEN when set.

Performance and Caching ⚙️

To improve performance and reduce API calls, git-branches batches git metadata and PR queries and caches PR data locally.

  • Git metadata: branches and last-commit info are fetched via a single git for-each-ref call.
  • PR list: fetched via REST in one call (/pulls?state=open&per_page=100) with ETag support; a small slice of recently closed PRs is also fetched to catch merges.
  • Disk cache: ~/.cache/git-branches/prs.json (configurable via XDG_CACHE_HOME or GIT_BRANCHES_CACHE_DIR) with timestamp, etag, and a {head.ref -> PR} map. Default TTL: 5 minutes.

Controls:

  • GIT_BRANCHES_OFFLINE=1: skip all GitHub API calls.
  • GIT_BRANCHES_PREFETCH_DETAILS=1: batch GraphQL for labels/reviews/body to make previews instant.
  • GIT_BRANCHES_NO_CACHE=1: ignore and do not write disk cache; do not use in-memory caches.
  • --refresh or GIT_BRANCHES_REFRESH=1: ignore existing cache and ETag this run, then write a fresh cache.

Environment Variables 🔧

GitHub & Performance

  • GIT_BRANCHES_OFFLINE=1: Run fully offline (no GitHub requests).
  • GIT_BRANCHES_NO_CACHE=1: Bypass disk/memory caching and ETag.
  • GIT_BRANCHES_REFRESH=1: Force refresh of caches for this run.
  • GIT_BRANCHES_PREFETCH_DETAILS=1: Prefetch PR details (GraphQL batches).
  • GIT_BRANCHES_SHOW_CHECKS=1: Allow fetching Actions status (same as --checks). If unset, cached checks are still displayed; no fetches.
  • GIT_BRANCHES_NO_PROGRESS=1: Disable spinners/progress indicators.

JIRA Integration

  • GIT_BRANCHES_JIRA_ENABLED=1: Enable/disable JIRA integration (default: enabled).
  • GIT_BRANCHES_JIRA_PATTERN=REGEX: Regex pattern for JIRA ticket detection (default: SRVKP-\d+).
  • GIT_BRANCHES_JIRA_BASE_URL=URL: JIRA instance URL (default: https://issues.redhat.com).

Customization

  • GIT_BRANCHES_BASE_BRANCH=BRANCH: Base branch for comparisons (default: main).
  • GIT_BRANCHES_CACHE_DIR=PATH: Custom cache directory location.
  • XDG_CACHE_HOME=PATH: Standard XDG cache directory (respects XDG Base Directory Specification).

Advanced Features 🚀

JIRA Integration

git-branches can automatically detect JIRA tickets in branch names and display ticket information in the preview:

# Default pattern matches SRVKP-1234 format
git-branches  # Branch: feature/SRVKP-1234-add-feature shows JIRA ticket info

# Customize JIRA pattern for your organization
git-branches --jira-pattern "PROJ-\d+" --jira-url "https://company.atlassian.net"

# Disable JIRA integration completely
git-branches --no-jira

Requirements: Install jayrah for JIRA CLI integration. Optionally install gum for enhanced markdown formatting.

Current Status Preview

View detailed git status and unpushed changes:

git-branches --status

Shows:

  • Current branch with tracking info
  • Staged, unstaged, and untracked file counts
  • List of changed files with status indicators
  • Unpushed commits with clickable GitHub links
  • PR information if available

Clickable Terminal Links

Modern terminals supporting OSC 8 escape sequences will make these elements clickable:

  • Branch names: Click to open GitHub branch page
  • PR numbers: Click to open pull request
  • JIRA tickets: Click to open ticket in JIRA
  • Commit hashes: Click to view commit on GitHub
  • URLs: Any URL in JIRA content becomes clickable

Supported terminals: iTerm2, Terminal.app (macOS), Windows Terminal, many Linux terminals.

Troubleshooting 🛠️

  • “fzf not found”: Install fzf and ensure it’s on PATH (brew install fzf, apt install fzf, etc.).

  • “Not in a git repository”: Run within a git repo.

  • No icons? Install a Nerd Font and configure your terminal to use it.

  • Low API rate limit? Set GITHUB_TOKEN (a classic or fine-grained PAT works).

  • Homebrew says “formula not in a tap”: create a local tap and install:

    TAP="${USER}/git-branches-dev"
    brew tap-new "$TAP"
    TAP_DIR="$(brew --repo "$TAP")"
    mkdir -p "$TAP_DIR/Formula"
    cp Formula/git-branches.rb "$TAP_DIR/Formula/"
    brew install --HEAD "$TAP/git-branches"

Development 🧪

  • Lint: make lint (auto-fix: make fix)
  • Tests: make test (pytest)
  • Dev loop: make dev (ruff fix → pytest → ruff format)
  • Format: make format (ruff)

License

See the repository’s LICENSE file.

About

select git branches with style

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Contributors