Skip to main content

ghswitch

A small CLI for juggling multiple GitHub identities (personal, work, client, …) across git clone, git push, and per-repo user.name / user.email.

  • Stores profile metadata in $XDG_CONFIG_HOME/ghswitch/profiles.json (0600)
  • Stores Personal Access Tokens in the OS keychain via keyring (macOS Keychain, Windows Credential Manager, GNOME Secret Service). Falls back to a 0600 JSON file if keyring isn't installed.
  • Picks the right profile from folder patterns or the SSH host alias in the repo's origin URL.
  • Cross-platform: Linux, macOS, Windows (WSL or native Python).

Install

pip install ghswitch-cli                  # core
pip install 'ghswitch-cli[keyring]'       # recommended — uses OS keychain for tokens

That installs a ghswitch console script. Verify with ghswitch --help.

If you'd rather not install: python3 ghswitch.py … works the same way.

Setup walkthrough

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_personal -C "you@personal"
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_work     -C "you@work"

Add each public key to the respective GitHub account.

2. Define SSH host aliases

Append to ~/.ssh/config:

Host github.com-personal
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

Host github.com-work
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

3. Register profiles

ghswitch add personal \
  --username alice \
  --email alice@personal.dev \
  --ssh-key ~/.ssh/id_ed25519_personal \
  --host-alias github.com-personal \
  --folder '~/code/personal/*' \
  --set-default

ghswitch add work \
  --username alice-corp \
  --email alice@workco.com \
  --ssh-key ~/.ssh/id_ed25519_work \
  --host-alias github.com-work \
  --folder '~/code/work/*'

For HTTPS + PAT instead of SSH, add --prompt-token (hidden input) or --token-stdin (read from stdin), and skip --ssh-key/--host-alias.

Commands

Command Purpose
ghswitch list List all profiles. The default is marked with *.
ghswitch add <name> [...] Add or update a profile. With no flags, prompts interactively.
ghswitch remove <name> Delete a profile and its stored token.
ghswitch use <name> Apply a profile to the current repo (user.name, user.email, core.sshCommand). Add --rewrite-remote to also flip the origin URL to the profile's host alias.
ghswitch clone <url> [profile] [dir] Clone with the chosen profile; auto-detects from URL host alias / folder patterns / default.
ghswitch status Show the current repo's identity and which profile (if any) it matches.
ghswitch whoami Print the default profile name.
ghswitch completion bash|zsh Emit a completion script.

Example workflows

Cloning into a work folder, hands-off

work has --folder '~/code/work/*' configured.

cd ~/code/work
ghswitch clone git@github.com:workco/api.git
# → auto-detects "work", rewrites URL to git@github.com-work:workco/api.git,
#   sets core.sshCommand to use the work key, and pins user.name/email.

Pushing from a personal repo

cd ~/code/personal/dotfiles
ghswitch use personal --rewrite-remote
git push

use --rewrite-remote flips origin to git@github.com-personal:owner/repo.git so subsequent git pull/push ride the right SSH key without env vars.

Verifying

ghswitch status
# repo:       /Users/alice/code/work/api
# remote:     git@github.com-work:workco/api.git
# user.name:  alice-corp
# user.email: alice@workco.com
# ssh:        ssh -i /Users/alice/.ssh/id_ed25519_work -o IdentitiesOnly=yes
# profile:    work  <- matches stored profile

Shell completion

# bash
ghswitch completion bash >> ~/.bash_completion
# zsh
ghswitch completion zsh > ~/.local/share/zsh-completions/_ghswitch

Auto-switching rules

When a profile match is needed (e.g. during clone without an explicit profile), ghswitch checks, in order:

  1. Folder patterns — longest-matching pattern wins. Patterns support ~ expansion and fnmatch-style globs.
  2. SSH host alias — if origin (or the URL passed to clone) uses a host matching a profile's host_alias.
  3. Default profile — set via add --set-default or implicitly the first profile added.

If none of these resolve and you didn't pass a name, clone exits with an error.

GitHub CLI integration

gh is not required, but if it's installed ghswitch plays well with it: SSH-based clones go through your ~/.ssh/config host aliases regardless of which tool you use, and HTTPS clones can use the PAT stored under the matching profile in your OS keychain.

Security notes

  • profiles.json and the fallback secrets.json are written 0600.
  • PATs are never written into git remote URLs on disk; for HTTPS clones the token is injected into the URL only for the git clone invocation, and the remote is reset to the canonical URL afterward.
  • core.sshCommand is set with IdentitiesOnly=yes so SSH won't fall back to another agent-loaded key.
  • Removing a profile also deletes its token from the keychain.

Development

pip install -e '.[dev]'
pytest

CI is in .github/workflows/:

  • test.yml — runs pytest on Linux, macOS, and Windows across Python 3.9 / 3.11 / 3.13 on every push and PR.
  • release.yml — on vX.Y.Z tag pushes, builds sdist + wheel, verifies the tag matches pyproject.toml's version, and creates a GitHub Release with auto-generated notes. PyPI trusted publishing is wired up but commented out — uncomment the pypi-publish job after configuring trusted publishing for the project.

To cut a release:

  1. Bump version in pyproject.toml and commit + push
  2. Go to Actions → release → Run workflow and enter the version number

The workflow creates the tag, builds sdist + wheel, creates a GitHub Release, and publishes to PyPI automatically.

Uninstall

pip uninstall ghswitch
rm -rf ~/.config/ghswitch        # Linux/macOS
# or %APPDATA%\ghswitch on Windows

Metadata

Release files for ghswitch-cli 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ghswitch-cli 1.0.0
File Size Uploaded
ghswitch_cli-1.0.0.tar.gz 15.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ghswitch-cli 1.0.0
File Interpreter ABI Platform
ghswitch_cli-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 26.1 kB

Release files / ghswitch_cli-1.0.0.tar.gz

Download URL ghswitch_cli-1.0.0.tar.gz
Size 15.4 kB
Tags Source
SHA-256 checksum
How to use checksums
1589cfa9f9483b74d7f8105057b61fc3a4b25b22198c0f34330aa78ed78ed9b8
BLAKE2b-256 checksum
How to use checksums
d0ce1cbfe851773a1b72dec06aa13bff63507b271fd64f74d3be2cc1631a47b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 18, 2026.

Transparency log

Release files / ghswitch_cli-1.0.0-py3-none-any.whl

Download URL ghswitch_cli-1.0.0-py3-none-any.whl
Size 10.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a6eefbbc2577e743835639f01a8712092652a1bccae74b4416521c832b552911
BLAKE2b-256 checksum
How to use checksums
5279da5cdbd2f1033cc244720108381d96ecc6e95718b2a669a1ba47f663f740
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page