v1.4.0
Documentation
   ██████╗  ██████╗████████╗ ██████╗
  ██╔═══██╗██╔════╝╚══██╔══╝██╔═══██╗
  ██║   ██║██║        ██║   ██║   ██║
  ██║   ██║██║        ██║   ██║   ██║
  ╚██████╔╝╚██████╗   ██║   ╚██████╔╝
   ╚═════╝  ╚═════╝   ╚═╝    ╚═════╝

Eight arms. One terminal. All of GitHub.

Python 3.10+ MIT License v1.1.0 requests rich InquirerPy

Octo is a fully interactive, terminal-native GitHub companion. Browse repositories, preview files with syntax highlighting, clone specific subdirectories, commit and push changes, search code, read issues and pull requests, and inspect contributor stats — all without leaving your shell.

It talks directly to the GitHub REST API with no dependencies beyond three pure-Python packages. No Electron, no browser tab, no copy-pasting URLs.

v1.1.0 — Security release
This version fixes a credential injection vulnerability present in v1.0.0. If you are running v1.0.0, upgrade immediately. See the Security section for full details.

Features

📂
Repo browser
Browse any public or private repo with live filtering by name or description. Paginated — no 100-repo cap.
📄
File preview
Inline syntax-highlighted preview for 40+ file types. Monokai theme, line numbers, up to 50 KB.
🔽
Sparse checkout
Clone any subdirectory, not the whole repo. Powered by git sparse-checkout. Fast on large monorepos.
⬆️
Commit & push
Stage files individually or all at once, write a commit message, and push — all from the terminal.
🔍
Code search
Search all files in a repo using the GitHub Search API. Select a result to preview the full file inline.
🐛
Issues & PRs
Browse open/closed issues and pull requests, read descriptions and comment threads inline.
📊
Repo stats
Contributor bar charts, language breakdown, and a 26-week commit activity histogram.
👤
Multi-account
Named token profiles — default, work, personal. Switch instantly from the main menu.
Starred repos
Browse your starred repositories with live filter. Same action loop as Browse — no context switching.
🔎
Repo search
Search GitHub globally by keyword and language. Sort by stars, forks, or recency.
GitHub Actions
View workflow runs, job status, and step-level failure details. No browser needed.
🌿
Branch manager
List, switch, create, and delete local branches. Detached HEAD detection built in.
📥
Pull / sync
Pull latest remote changes into any local clone from the main menu. History-aware.
🗂️
Stash manager
Stash, pop, apply, drop, and list stashes — full stash workflow in one menu.
🔀
PR diff viewer
View changed files and read inline patches for any pull request with Monokai highlighting.

Installation

Requirements: Python 3.10 or later · git on your $PATH

Step 1 — Get the project

bash
# Clone from GitHub
git clone https://github.com/threed2y/Octo-Git.git
cd Octo-Git

Step 2 — Create a virtual environment

bash
python -m venv .venv

Activate it:

PlatformCommand
macOS / Linuxsource .venv/bin/activate
Windows (CMD).venv\Scripts\activate.bat
Windows (PowerShell).venv\Scripts\Activate.ps1

Your prompt will show (.venv) when active.

Step 3 — Install dependencies

bash
pip install -r requirements.txt

Step 4 — Run

bash
python -m octo
Optional — install as a shell command
Run pip install -e . once to register octo as a command in your virtual environment. After that, just type octo from any directory while the venv is active.

Authentication

Octo works without a token but GitHub limits unauthenticated requests to 60 per hour. A Personal Access Token raises this to 5,000 per hour and unlocks private repositories.

Generate a token

Open GitHub token settings
GitHub → Settings → Developer Settings → Personal Access Tokens → Tokens (classic)
Generate new token (classic)
Give it a name like octo-cli so you can identify it later.
Set scopes
Check repo. Add read:org if you want to browse organisation repositories.
Copy the token
You will only be shown it once. Copy it before closing the page.

Add the token to Octo

Main menu  →  Setup Token

Enter a profile name (e.g. default) and paste your token. Octo validates it against the GitHub API immediately — the token is only saved if validation succeeds.

Security note
Tokens are stored in ~/.octo_profiles.json with 0600 permissions on Unix. The token never appears in process arguments or shell history. See the Security section for full details.

Usage overview

Launch Octo with:

python -m octo
# or, if installed via pip install -e .
octo

Keyboard controls

KeyAction
/ Move through options
EnterSelect / confirm
SpaceToggle checkbox (file staging)
Ctrl-CCancel / exit at any point

📂 Browse repositories

Select Browse Repositories
From the main menu.
Enter a username or org
e.g. django, microsoft, torvalds. Recent usernames are offered as a quick-pick list — no retyping. Fetches all repos with full pagination — no 100-repo cap.
Filter (optional)
Type a keyword to filter by name, description, or repository topics. Press Enter with a blank input to show all.
Select a repository
A summary card appears showing stars, forks, language, license, and open issue count.
Choose an action
Browse Files, Search Code, Issues & PRs, GitHub Actions, Stats & Insights, Create Issue, Open in Browser, or Copy URL.

📄 File browser & preview

Navigate the directory tree with arrow keys. Folders are prefixed with . Selecting a file opens an inline syntax-highlighted preview (up to 50 KB, with line numbers).

Supported preview types

.py .js .ts .tsx .jsx .go .rs .java .c .cpp .rb .php .html .css .scss .json .yaml .toml .md .sh .xml .svg .ini .conf and more.

Binary files and unsupported extensions display the file's GitHub URL instead of attempting a preview.

After any preview, the action menu offers Open in Browser, Copy URL, and Download file — saving the raw file directly to disk at a path you choose.

🔽 Sparse checkout

Navigate to any folder in the file browser and select Clone this path. Octo uses git sparse-checkout to download only that subdirectory — not the entire repository. This is significantly faster for large monorepos.

Browse Files  →  navigate into any folder  →  Clone this path

The clone is saved as ./repo_folder_clone/ in your current working directory. Octo asks if you want to open it in $EDITOR immediately, then offers to start a commit & push session.

Clone history
Every clone is automatically recorded in ~/.octo_clones.json. Access them from Clone History in the main menu to commit, push, or reopen without navigating the file browser again.

How sparse checkout works

git — what Octo runs internally
git clone --no-checkout --depth 1 --branch BRANCH REPO_URL TARGET
git sparse-checkout init --cone
git sparse-checkout set PATH
git checkout BRANCH

⬆️ Commit & push

Available from the main menu, or automatically offered after a sparse checkout.

Select Commit & Push
Opens with a quick-pick list of your known local clones. Choose one or enter a path manually.
View changed files
Octo runs git status and displays all modified, added, and deleted files.
Stage
Choose to stage everything (git add -A) or pick files individually from a checkbox list.
Commit message
Enter a commit message. An empty message aborts without running any git command.
Push
Optionally pull remote changes first to prevent rejection. Octo handles authentication securely — the token never appears in process arguments. Detached HEAD is detected early with a clear explanation.

🐛 Issues & Pull Requests

Browse  →  select repo  →  Issues & Pull Requests

Choose between Issues and Pull Requests. Filter by state (open / closed / all) and optionally by label. Select any item to read its full body and optionally load up to 10 comment threads inline.

Each detail view shows: number, title, state, author, creation date, last updated, labels, assignees, and a direct URL. Pull Requests also offer a View changed files / diff prompt — showing a file summary table and inline patch view with Monokai highlighting.

Every issue and PR has Open in Browser and Copy URL at the bottom of its detail view.

📊 Repo stats

Browse  →  select repo  →  Stats & Insights

Three views, available individually or all at once:

ViewWhat it shows
Top ContributorsRanked list of up to 20 contributors with commit counts and proportional fill bars
Language BreakdownBytes per language, percentage of total, colour-coded bars
Commit Activity26-week histogram, bars heat-coded by activity level (bright = high, dim = low)
Note
GitHub computes commit activity statistics asynchronously. If the data isn't ready, Octo retries once after 3 seconds and tells you to try again if it's still computing.

🔎 Search repositories

Main menu  →  Search Repositories

Search GitHub globally for repositories by keyword. Results are sorted by your choice of stars, recently updated, forks, or best match. An optional language filter appends language:<lang> to the query.

Selecting a result drops you into the same repo action loop as Browse — Browse Files, Search Code, Issues & PRs, Actions, Stats, and more.

Starred repos

Main menu  →  Starred Repos

Fetches up to 500 of your starred repositories (requires a token). Supports the same live keyword filter as Browse — matches name, description, full name, and topics. All repo actions available after selection.

🕓 Clone history

Main menu  →  Clone History

Every successful sparse checkout is recorded in ~/.octo_clones.json (up to 20 entries, deduplicated by path). Entries whose directories no longer exist are pruned automatically.

From the Clone History menu you can:

ActionWhat it does
Commit & PushStage, commit, and push without leaving Octo
Open in EditorLaunch $EDITOR pointed at the directory
Open in BrowserOpen the source GitHub repo URL in your browser
Copy pathCopy the local directory path to clipboard
Remove entryRemove from history without deleting the directory

⬇️ Pull / sync

Main menu  →  Pull / Sync

Pull latest remote changes into any local clone. Picks from your clone history or accepts a manual path. Shows the current branch before pulling.

Detached HEAD
Sparse checkouts can leave the repo in detached HEAD state. Octo detects this and refuses to pull with a clear explanation — use the Branch Manager to switch to a named branch first.

± View local diff

Main menu  →  View Local Diff

Renders git diff output inline with Monokai syntax highlighting before you commit. Four modes:

ModeEquivalent command
Unstaged changesgit diff
Staged changesgit diff --staged
All changes vs HEADgit diff HEAD
Between commits / branchesgit diff <ref-a> <ref-b>

🌿 Branch manager

Main menu  →  Branch Manager

Manage local branches for any clone in your history. The current branch is shown at the top of every action.

ActionDetail
Switch branchCheckout any local branch
Create branchName and base branch — creates and checks out immediately
Delete branchSafe delete (-d) or force delete (-D) with confirmation
List all branchesLocal and remote, with current branch highlighted

🗂️ Stash manager

Main menu  →  Stash Manager

Full stash workflow without leaving Octo.

ActionDetail
StashStash current changes with an optional message. Includes untracked files (-u).
PopApply and remove the latest stash
ApplyApply a selected stash without removing it
DropDelete a selected stash
ListShow all stashes in a table with their messages

GitHub Actions

Browse  →  select repo  →  GitHub Actions

Shows the last 30 workflow runs for a repository. Each run displays a status icon, branch, trigger event, and duration.

IconMeaning
Success
Failure or timed out
In progress
Cancelled

Selecting a run shows all jobs in a table. Failed jobs expand to show which individual step failed, so you can identify the problem without opening the browser.

✏️ Create an issue

Browse  →  select repo  →  Create an Issue

Opens a short form: title (required), optional body, and optional labels fetched from the repository. A preview panel shows the issue before you submit. On success, the new issue URL is displayed and you can open it in the browser immediately.

Requires a token
Creating issues requires a GitHub token with the repo scope. Add one via Setup Token in the main menu.

👤 Profiles

Octo supports multiple named token profiles so you can switch between GitHub accounts without re-entering tokens.

Add a profile

Main menu  →  Setup Token
Profile name: work

Switch profiles

Main menu  →  Manage Profiles  →  Switch active profile

Storage

Profiles are stored in ~/.octo_profiles.json. The file is created with 0600 permissions on Unix. Writes are atomic — a crash or interrupt during save cannot leave the file corrupt.

~/.octo_profiles.json
{
  "default": "ghp_...",
  "work":    "ghp_...",
  "oss":     "ghp_..."
}

🔒 Security

v1.1.0 is a dedicated security release. The following issues were identified in v1.0.0 and patched.

High
Shell injection via credential helper — fixed
The raw token was interpolated into a bash shell function string and passed to git. Tokens containing $, backticks, !, or \ could trigger arbitrary command execution. Fixed by writing the token to a 0600 temp file and passing only the helper script path to git — the token value never enters any shell evaluation context.
Medium
Token saved before validation — fixed
In v1.0.0, an invalid token was persisted before being checked. Now the GitHub API is called first; the token is only written to disk on HTTP 200.
Medium
Non-atomic profile writes — fixed
A crash or Ctrl-C mid-write could leave ~/.octo_profiles.json truncated with no recovery path. Writes now use mkstemp + os.replace(), which is atomic on POSIX and Win32.
Low
Loose permissions not detected — fixed
The profiles file could be world-readable in Docker or CI environments without any warning. Octo now checks on startup and shows the exact chmod command if the permissions are too broad.
Low
Implicit TLS verification — fixed
All requests calls now pass verify=True explicitly, making intent clear and preventing environment-variable overrides from silently disabling certificate verification.

Credential security model

When Octo needs to authenticate a git operation (clone, push), it:

Secure credential flow — v1.1.0
# 1. Token written to a temp file (0600, never in any string interpolation)
token_file = mkstemp()   # e.g. /tmp/.octo_tok_abc123

# 2. A helper script written (0700) that reads from the token file
helper = "#!/bin/sh\necho username=token\ncat TOKEN_FILE\n"

# 3. Git receives only the SCRIPT PATH — never the token value
git -c credential.helper=HELPER_PATH clone ...

# 4. Both temp files deleted in a finally block — even on failure
os.unlink(token_file)
os.unlink(helper)

Platform support

PlatformRunsCredential helperEditor launchFile permissions
macOS✓ 0600
Linux✓ 0600
Windows (CMD / PowerShell)✓ .bat helper⚠ ACL-based
Windows (WSL)⚠ depends on setup✓ 0600

Dependencies

PackageVersionPurpose
requests≥ 2.31GitHub API HTTP calls
rich≥ 13.7Terminal UI — panels, tables, syntax highlighting
InquirerPy≥ 0.3.4Interactive menus and prompts
pyperclip≥ 1.8 (optional)Cross-platform clipboard support. Falls back to pbcopy / xclip / clip if not installed.

The first three are required. pyperclip is optional — uncomment it in requirements.txt to install.

Project structure

repository layout
Octo-Git/
├── octo/
│   ├── __init__.py      # package metadata, version
│   ├── __main__.py      # enables python -m octo
│   └── core.py          # all application logic
├── docs/
│   └── preview_main.txt # ASCII preview reference
├── tests/               # test suite
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── pyproject.toml       # build config + entry point
└── requirements.txt     # runtime dependencies

Changelog

v1.4.0
May 5, 2026
Added Fixed
  • Pull / Sync — pull latest remote changes from the main menu, with detached HEAD detection
  • Branch Manager — list, switch, create, and delete local branches
  • View Local Diff — git diff rendered inline with Monokai highlighting, four scope modes
  • Stash Manager — stash, pop, apply, drop, and list stashes interactively
  • File download — download any previewed file to disk via GitHub raw URL
  • Language filter in global repo search — appends language:<lang> to query
  • Fixed: detached HEAD warning in commit & push flow
  • Fixed: pull-before-push prompt prevents remote divergence errors
  • Fixed: issue body input replaced with inquirer.text() — consistent with all other inputs
v1.3.0
April 5, 2026
Added Fixed
  • Clone History — tracks up to 20 clones in ~/.octo_clones.json with commit, open, copy, and remove actions
  • Repository Search — global GitHub search with sort and language filter
  • Starred Repositories — browse up to 500 starred repos with live filter
  • Recent Usernames — last 10 usernames as quick-pick in Browse flow
  • GitHub Actions viewer — runs, jobs, step-level failure details
  • PR Diff viewer — file summary table and inline patch with Monokai highlighting
  • Create Issue — title, body, labels, preview before submit
  • Open in Browser and Copy URL — available across all repo, file, and issue views
  • Shared _repo_action_loop() — all entry points (Browse, Search, Starred) behave identically
  • Topic filtering in Browse — filter matches repository topics field
  • Fixed: private repos now visible when browsing your own username
  • Fixed: non-JSON GitHub error responses no longer crash _get_json
  • Fixed: file browser shows correct error when path points to a file not a directory
  • Fixed: datetime.utcfromtimestamp deprecated in Python 3.12 — replaced
  • Fixed: rate limit tracking via X-RateLimit-Remaining header on every response
  • Fixed: repo action menu now loops — no longer ejects to username prompt after an action
  • Fixed: profile manager reachable even when no profiles are saved
v1.1.0
March 31, 2025
Security Fixed
  • Fixed shell injection vulnerability in git credential helper
  • Token now validated before saving — invalid tokens are rejected at entry
  • Atomic profile writes via mkstemp + os.replace()
  • Loose permissions warning on startup and in profile manager
  • Explicit verify=True on all outbound requests
  • File browser no longer exits after cloning a path
  • $EDITOR with arguments (e.g. code --wait) now works correctly
  • Git presence check before clone and push — clear error if not on PATH
  • Empty file selection in interactive staging now aborts cleanly
  • Repo path validated before commit — distinct errors for missing path vs. non-repo
  • Corrupt profiles file shows a warning instead of silently resetting
v1.0.0
January 1, 2025
Added
  • Interactive repository browser with real-time filter
  • Syntax-highlighted file preview — 40+ types, Monokai theme
  • Sparse checkout — clone any subdirectory via git sparse-checkout
  • Commit & push workflow with interactive file staging
  • GitHub code search scoped to a repository
  • Issues & Pull Requests viewer with comment threads
  • Repo stats: contributors, language breakdown, 26-week activity
  • Multi-account token profiles in ~/.octo_profiles.json
  • Full pagination — no 100-repo or 100-branch cap
  • Cyan / electric-blue terminal theme

Roadmap

Planned and considered features for future releases.

v1.5
Fuzzy finder
Replace flat selection lists with an incremental fuzzy filter for repo selection and file browsing — faster for large orgs and deep directory trees.
v1.5
Config file (~/.octorc)
User-configurable defaults: preferred editor, default clone directory, preview theme, max preview file size, and whether to always open editor after clone.
v1.5
Ahead / behind counts
Show how many commits each local branch is ahead or behind its remote tracking branch — visible in the Branch Manager list view.
v1.6
PR review submission
Leave review comments, approve, or request changes on pull requests — extending the existing diff viewer into a full review workflow.
v1.6
Actions log streaming
Stream live logs from in-progress workflow runs via the GitHub log API — currently only completed runs are shown.
Idea
Notification reader
Read GitHub notifications — PR mentions, review requests, CI failures — directly in Octo with unread counts on the main menu.
Idea
Release manager
Browse a repo's releases, download assets, and draft or publish new releases with a tag and release notes.
Idea
Gist manager
List, create, edit, and delete your GitHub Gists without leaving the terminal.

Contributing

Contributions are welcome. Here's how to get a development environment running:

bash
git clone https://github.com/threed2y/Octo-Git.git
cd Octo-Git
python -m venv .venv
source .venv/bin/activate
pip install -e .
python -m octo

Code style

RuleDetail
Type hintsPython 3.10+ style — str | None, not Optional[str]
Colour tokensAlways use the module-level constants (C, CD, OK, etc.) — never hardcode "cyan" inline
OutputUse _ok(), _err(), _warn(), _info(), _panel() — don't call console.print() directly in feature functions
SecretsNever interpolate tokens into shell strings. Use _git_env_with_token() for all git operations that need auth

Submitting a pull request

Fork and branch
git checkout -b feat/my-feature
Make your changes
Keep commits focused. One feature or fix per PR.
Open a PR against main
Describe what changed and why. Reference any related issues.