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.
# 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- 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).
- 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
uv tool install git+https://github.com/chmouel/git-branches.git@mainHomebrew (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- 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)
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.
-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)
--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)
ctrl-o: Open the PR for the highlighted ref in the default browseralt-k: Force-delete highlighted local branch (quick action)
There are two ways to enable completion:
- Built-in generator (recommended)
- Static scripts under
contrib/
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 # FishPersistent 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-nameoffers remote name completion fromgit remote.--pr-statescompletes toOPEN,CLOSED,MERGED, orALL.
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.
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- 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
originor the first remote. - For
-sand preview CI status, calls the GitHub API withAuthorization: Bearer $GITHUB_TOKENwhen set.
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-refcall. - 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 viaXDG_CACHE_HOMEorGIT_BRANCHES_CACHE_DIR) withtimestamp,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.--refreshorGIT_BRANCHES_REFRESH=1: ignore existing cache and ETag this run, then write a fresh cache.
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.
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).
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).
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-jiraRequirements: Install jayrah for JIRA CLI integration. Optionally install gum for enhanced markdown formatting.
View detailed git status and unpushed changes:
git-branches --statusShows:
- 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
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.
-
“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"
- Lint:
make lint(auto-fix:make fix) - Tests:
make test(pytest) - Dev loop:
make dev(ruff fix → pytest → ruff format) - Format:
make format(ruff)
See the repository’s LICENSE file.