{"id":34048565,"url":"https://github.com/chmouel/git-branches","last_synced_at":"2026-04-08T12:02:36.998Z","repository":{"id":309679639,"uuid":"1037152903","full_name":"chmouel/git-branches","owner":"chmouel","description":"select git branches with style","archived":false,"fork":false,"pushed_at":"2025-10-28T14:32:18.000Z","size":389,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-12T17:40:28.167Z","etag":null,"topics":["fzf","git","github"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chmouel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-08-13T06:30:49.000Z","updated_at":"2025-10-28T14:32:21.000Z","dependencies_parsed_at":"2025-08-13T08:30:20.921Z","dependency_job_id":"33ed2abc-f6a1-4ec6-894d-b41ebe7948cc","html_url":"https://github.com/chmouel/git-branches","commit_stats":null,"previous_names":["chmouel/git-branches"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/chmouel/git-branches","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgit-branches","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgit-branches/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgit-branches/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgit-branches/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chmouel","download_url":"https://codeload.github.com/chmouel/git-branches/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgit-branches/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31554110,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T10:21:54.569Z","status":"ssl_error","status_checked_at":"2026-04-08T10:21:38.171Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["fzf","git","github"],"created_at":"2025-12-14T00:05:48.546Z","updated_at":"2026-04-08T12:02:36.957Z","avatar_url":"https://github.com/chmouel.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-branches\n\n![PyPI - Version](https://img.shields.io/pypi/v/git-branches)\n[![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-3776AB?logo=python\u0026logoColor=white)](#requirements)\n[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-46A3FF)](https://docs.astral.sh/ruff/)\n[![Pre-commit](https://github.com/chmouel/git-branches/actions/workflows/precommit.yml/badge.svg)](https://github.com/chmouel/git-branches/actions/workflows/precommit.yml)\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue)](../../LICENSE)\n\nAn 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.\n\n\u003cimg width=\"1755\" height=\"1135\" alt=\"image\" src=\"https://github.com/user-attachments/assets/d3a19433-da27-4ba0-9b94-587b6937f1ad\" /\u003e\n\n🍺 Homebrew CI: [![Homebrew CI](https://github.com/chmouel/git-branches/actions/workflows/homebrew.yml/badge.svg)](https://github.com/chmouel/git-branches/actions/workflows/homebrew.yml)\n\n## TL;DR ⚡️\n\n```bash\n# Install (Homebrew tap)\nbrew tap chmouel/git-branches https://github.com/chmouel/git-branches\nbrew install --HEAD chmouel/git-branches/git-branches\n\n# Browse local branches (preview on top)\ngit-branches\n\n# Browse remote branches (pick a remote)\ngit-branches -r\n\n# Show pushed-status icons for local branches\ngit-branches -s   # add -S to show all\n\n# Show GitHub Actions status (fetch over network)\ngit-branches --checks\n\n# Current status with unpushed changes and PR info\ngit-branches --status\n\n# Custom JIRA pattern and base branch\ngit-branches --jira-pattern \"PROJ-\\d+\" --base-branch develop\n\n# Super fast offline mode (no network, cached data only)\ngit-branches --fast\n```\n\n## Highlights\n\n- **fzf-native UX**: reverse list, previews, key bindings, multi-select for deletes.\n- **Rich preview**: PR status (Open/Draft/Merged/Closed), OSC-8 clickable links to PRs, CI combined status, and the last 10 commits with colors.\n- **Clickable terminal links**: Branch names, PR numbers, JIRA tickets, and URLs are clickable using OSC 8 escape sequences (supported by modern terminals).\n- **JIRA integration**: Automatically detect JIRA tickets in branch names and show ticket details using [jayrah](https://github.com/ankitpokhrel/jira-cli) with optional [gum](https://github.com/charmbracelet/gum) formatting.\n- **GitHub awareness**: shows whether a local branch exists on the remote (`-s`) and the CI status for the PR head commit.\n- **One-keystroke actions**: checkout, open PR (`ctrl-o`), delete quickly (`alt-k`).\n\n## Requirements\n\n- git and fzf on PATH\n- Python 3.12+ (uv-managed)\n- Optional: `GITHUB_TOKEN` (improves rate limits and enables private repos)\n- Optional: a Nerd Font for icons (fallback text is still readable)\n- Optional: [jayrah](https://github.com/chmouel/jayrah) for JIRA ticket integration\n- Optional: [gum](https://github.com/charmbracelet/gum) for enhanced JIRA ticket formatting\n- Optional: [gh](https://cli.github.com/) GitHub CLI for enhanced PR information in previews\n\n## Installation 🍺\n\n### [UV](https://docs.astral.sh/uv/getting-started/installation/)\n\n  ```bash\n  uv tool install git+https://github.com/chmouel/git-branches.git@main\n  ```\n\n### [Homebrew](https://brew.sh/) (Tap)\n\nYou can install via a Homebrew tap that ships a Formula for `git-branches`.\n\nOption A — tap this repo directly (HEAD installs from the main branch):\n\n```bash\nbrew tap chmouel/git-branches https://github.com/chmouel/git-branches\nbrew install --HEAD chmouel/git-branches/git-branches\n```\n\n## Quickstart 🚀\n\n- Browse and checkout local branches:\n  - `git-branches`\n- Browse remotes and checkout (creates tracking branch if needed):\n  - `git-branches -r` (select remote interactively)\n  - `git-branches -R origin`\n- Browse GitHub pull requests and act on them:\n  - `git-branches --prs` (Enter=checkout, Alt-w=create worktree)\n- Deletion workflows:\n  - `git-branches -d` (delete local; multi-select)\n  - `git-branches -D -R origin` (delete remote)\n- See if local branches exist on the remote:\n  - `git-branches -s` (shows pushed status with default limit of 10)\n  - `git-branches -s -S` (disable default limit)\n\n### Pull Request Browser\n\n`git-branches --prs` opens an fzf view of the repository's GitHub pull requests (requires a GitHub remote and the [`gh` CLI](https://cli.github.com/)). 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 `\u003crepo\u003e-worktrees` directory.\n\nBy default only **OPEN** pull requests are shown. Use `--pr-states \u003cSTATE...\u003e` (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.\n\n## Command-line options 🧭\n\n### Core Options\n\n- `-r`: Browse remote branches (choose remote via fzf)\n- `-R \u003cremote\u003e`: Browse a specific remote (e.g., origin)\n- `-d`: Delete local branches (multi-select)\n- `-D`: Delete remote branches (multi-select)\n- `-s`: Show pushed status for local branches (GitHub API)\n- `-n \u003cN\u003e`: Limit to first N branches\n- `-S`: With `-s`, disable default limit (show all)\n- `-C`: Disable colors\n- `-l`: List-only mode (no checkout)\n- `--fast`: Super fast offline mode (no network calls, minimal processing)\n- `--refresh`: Force refresh of PR cache (ignore stale cache and ETag)\n- `--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.\n- `--worktree`: Show only branches that have worktrees\n- `--prs`: Browse GitHub pull requests (Enter=checkout branch, Alt-w=create worktree with sanitized title)\n- `--pr-states \u003cSTATE...\u003e`: Filter PR browser states (default: OPEN; use ALL to include every state)\n\n### Preview \u0026 Integration Options\n\n- `--status`: Show current git status and unpushed changes preview\n- `--jira-pattern REGEX`: Custom regex pattern for JIRA ticket detection (e.g., `'PROJ-\\d+'`, default: `'SRVKP-\\d+'`)\n- `--jira-url URL`: JIRA base URL for ticket links (default: `https://issues.redhat.com`)\n- `--no-jira`: Disable JIRA ticket integration in previews\n- `--base-branch BRANCH`: Base branch for comparisons (default: `main`)\n\n## Key bindings (fzf)\n\n- `ctrl-o`: Open the PR for the highlighted ref in the default browser\n- `alt-k`: Force-delete highlighted local branch (quick action)\n\n## Shell Completion 🔌\n\nThere are two ways to enable completion:\n\n- Built-in generator (recommended)\n- Static scripts under `contrib/`\n\n### Built-in (Click-based)\n\n`git-branches` can emit completion scripts for Bash, Zsh, Fish, and PowerShell.\n\nQuick enable in the current shell session:\n\n```bash\neval \"$(uv run git-branches completion --shell bash)\"   # Bash\neval \"$(uv run git-branches completion --shell zsh)\"    # Zsh\nuv run git-branches completion --shell fish | source     # Fish\n```\n\nPersistent enablement:\n\n- Bash: add `eval \"$(git-branches completion --shell bash)\"` to `~/.bashrc`\n- Zsh: add `eval \"$(git-branches completion --shell zsh)\"` to `~/.zshrc`\n- Fish: add `git-branches completion --shell fish \u003e ~/.config/fish/completions/git-branches.fish`\n\nExtras:\n\n- `-R/--remote-name` offers remote name completion from `git remote`.\n- `--pr-states` completes to `OPEN`, `CLOSED`, `MERGED`, or `ALL`.\n\n### Static scripts (contrib/)\n\nIf you prefer static files, use the scripts under `contrib/`:\n\n- Zsh: `_git-branches`\n- Bash: `git-branches.bash`\n- Fish: `git-branches.fish`\n\nFollow the comments in each file for installation.\n\n### Arch Linux (PKGBUILD / AUR-style)\n\nThis repository includes a `PKGBUILD` under `aur/` for a `-git` style package (builds from HEAD).\n\n- Build locally with makepkg (requires `base-devel`):\n\n```bash\ncd aur\nmakepkg -sci --noconfirm\n```\n\n## How it works\n\n- Uses git for data (branch lists, recent commits) and fzf for the UI.\n- Detects GitHub repository from the upstream of the current branch when possible, falling back to `origin` or the first remote.\n- For `-s` and preview CI status, calls the GitHub API with `Authorization: Bearer $GITHUB_TOKEN` when set.\n\n## Performance and Caching ⚙️\n\nTo improve performance and reduce API calls, `git-branches` batches git metadata and PR queries and caches PR data locally.\n\n- Git metadata: branches and last-commit info are fetched via a single `git for-each-ref` call.\n- PR list: fetched via REST in one call (`/pulls?state=open\u0026per_page=100`) with ETag support; a small slice of recently closed PRs is also fetched to catch merges.\n- Disk cache: `~/.cache/git-branches/prs.json` (configurable via `XDG_CACHE_HOME` or `GIT_BRANCHES_CACHE_DIR`) with `timestamp`, `etag`, and a `{head.ref -\u003e PR}` map. Default TTL: 5 minutes.\n\nControls:\n\n- `GIT_BRANCHES_OFFLINE=1`: skip all GitHub API calls.\n- `GIT_BRANCHES_PREFETCH_DETAILS=1`: batch GraphQL for labels/reviews/body to make previews instant.\n- `GIT_BRANCHES_NO_CACHE=1`: ignore and do not write disk cache; do not use in-memory caches.\n- `--refresh` or `GIT_BRANCHES_REFRESH=1`: ignore existing cache and ETag this run, then write a fresh cache.\n\n## Environment Variables 🔧\n\n### GitHub \u0026 Performance\n\n- `GIT_BRANCHES_OFFLINE=1`: Run fully offline (no GitHub requests).\n- `GIT_BRANCHES_NO_CACHE=1`: Bypass disk/memory caching and ETag.\n- `GIT_BRANCHES_REFRESH=1`: Force refresh of caches for this run.\n- `GIT_BRANCHES_PREFETCH_DETAILS=1`: Prefetch PR details (GraphQL batches).\n- `GIT_BRANCHES_SHOW_CHECKS=1`: Allow fetching Actions status (same as `--checks`). If unset, cached checks are still displayed; no fetches.\n- `GIT_BRANCHES_NO_PROGRESS=1`: Disable spinners/progress indicators.\n\n### JIRA Integration\n\n- `GIT_BRANCHES_JIRA_ENABLED=1`: Enable/disable JIRA integration (default: enabled).\n- `GIT_BRANCHES_JIRA_PATTERN=REGEX`: Regex pattern for JIRA ticket detection (default: `SRVKP-\\d+`).\n- `GIT_BRANCHES_JIRA_BASE_URL=URL`: JIRA instance URL (default: `https://issues.redhat.com`).\n\n### Customization\n\n- `GIT_BRANCHES_BASE_BRANCH=BRANCH`: Base branch for comparisons (default: `main`).\n- `GIT_BRANCHES_CACHE_DIR=PATH`: Custom cache directory location.\n- `XDG_CACHE_HOME=PATH`: Standard XDG cache directory (respects XDG Base Directory Specification).\n\n## Advanced Features 🚀\n\n### JIRA Integration\n\ngit-branches can automatically detect JIRA tickets in branch names and display ticket information in the preview:\n\n```bash\n# Default pattern matches SRVKP-1234 format\ngit-branches  # Branch: feature/SRVKP-1234-add-feature shows JIRA ticket info\n\n# Customize JIRA pattern for your organization\ngit-branches --jira-pattern \"PROJ-\\d+\" --jira-url \"https://company.atlassian.net\"\n\n# Disable JIRA integration completely\ngit-branches --no-jira\n```\n\n**Requirements**: Install [jayrah](https://github.com/ankitpokhrel/jira-cli) for JIRA CLI integration. Optionally install [gum](https://github.com/charmbracelet/gum) for enhanced markdown formatting.\n\n### Current Status Preview\n\nView detailed git status and unpushed changes:\n\n```bash\ngit-branches --status\n```\n\nShows:\n\n- Current branch with tracking info\n- Staged, unstaged, and untracked file counts\n- List of changed files with status indicators\n- Unpushed commits with clickable GitHub links\n- PR information if available\n\n### Clickable Terminal Links\n\nModern terminals supporting OSC 8 escape sequences will make these elements clickable:\n\n- **Branch names**: Click to open GitHub branch page\n- **PR numbers**: Click to open pull request\n- **JIRA tickets**: Click to open ticket in JIRA\n- **Commit hashes**: Click to view commit on GitHub\n- **URLs**: Any URL in JIRA content becomes clickable\n\nSupported terminals: iTerm2, Terminal.app (macOS), Windows Terminal, many Linux terminals.\n\n## Troubleshooting 🛠️\n\n- “fzf not found”: Install fzf and ensure it’s on PATH (`brew install fzf`, `apt install fzf`, etc.).\n- “Not in a git repository”: Run within a git repo.\n- No icons? Install a Nerd Font and configure your terminal to use it.\n- Low API rate limit? Set `GITHUB_TOKEN` (a classic or fine-grained PAT works).\n- Homebrew says “formula not in a tap”: create a local tap and install:\n\n  ```bash\n  TAP=\"${USER}/git-branches-dev\"\n  brew tap-new \"$TAP\"\n  TAP_DIR=\"$(brew --repo \"$TAP\")\"\n  mkdir -p \"$TAP_DIR/Formula\"\n  cp Formula/git-branches.rb \"$TAP_DIR/Formula/\"\n  brew install --HEAD \"$TAP/git-branches\"\n  ```\n\n## Development 🧪\n\n- Lint: `make lint` (auto-fix: `make fix`)\n- Tests: `make test` (pytest)\n- Dev loop: `make dev` (ruff fix → pytest → ruff format)\n- Format: `make format` (ruff)\n\n## License\n\nSee the repository’s `LICENSE` file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchmouel%2Fgit-branches","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchmouel%2Fgit-branches","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchmouel%2Fgit-branches/lists"}