gw
Switch between multiple git/GitHub accounts, per repository, and see which account is active right in your shell prompt.
Install
pipx install gwitch
Published on PyPI as gwitch; installs the gw command. Or, from a
checkout of this repository:
pipx install .
Quick start
gw account add personal
gw account add work
cd ~/code/some-repo
gw use personal
gw status
Shell prompt
gw init zsh # or bash / fish
prints a small shell function, plus a one-line instruction for wiring it
into your prompt — paste both into your shell config yourself. gw never
edits your shell rc files automatically.
gw init zsh --install # or bash
--install does the wiring for you, for zsh/bash only (not fish
yet): it writes a gw-prompt script to ~/.local/bin/gw-prompt and a
gw-check script to ~/.local/bin/gw-check (the cd-triggered account-check
described below), and appends two marked blocks to your rc file — one per
script. It's idempotent — safe to re-run. Note for macOS bash users:
~/.bashrc isn't read by login shells (Terminal and iTerm start bash as a
login shell), so unless you've already wired ~/.bashrc to be sourced from
~/.bash_profile, you'll need to add that yourself for the installed
integration to take effect.
What gw use <account> changes
user.name/user.email— local to the current repo only (git config --local)core.sshCommand— forces the SSH key registered for that accountgw.account— a marker read bygw statusand the shell prompt functiongw-remote-map.<remote URL>.account— records this repo's remote in global git config, for the cd-triggered mismatch check below
gw use also records this repo's remote-to-account mapping in global
git config (for the cd-triggered mismatch check, see below) — everything
else stays local-only. None of this touches ~/.ssh/config or ssh-agent.
Remote-account mismatch check
With gw init <shell> --install, a gw-check script is wired to run every
time your shell cds into a different directory. If the repo you land in
has an origin remote that gw use <account> has previously recorded, and
the account currently active in that repo doesn't match, it prints a
warning to stderr telling you which account to switch to. It never blocks
or changes anything — it's purely informational.
Known limitations
gh (GitHub CLI) authentication is global, not per-repo. GitHub CLI's
authenticated account is global to your machine (gh keeps one active user
per host), not per-repo — that's inherent to how gh itself works. gw use <account> will call gh auth switch for you, which changes gh's active
account machine-wide, even for other repos/terminal tabs, until you gw use
a different account somewhere else. Your git identity and SSH key stay
correctly isolated per-repo regardless.
gw status shows both this repo's git identity and gh's currently active
account as separate lines, so if they've drifted apart it's visible rather
than silent.
Linked git worktrees share git identity. git config --local in a
linked worktree (created via git worktree add) resolves to the same
shared config file as the main checkout — git only isolates local config
per-worktree if the repo opts into extensions.worktreeConfig, which gw
does not assume. That means gw use <account> run inside a linked worktree
changes the identity for the main checkout and every sibling worktree of
that repo too, not just the worktree you ran it in. gw use detects this
and prints a warning when you run it inside a linked worktree, but it does
not block the switch or set up per-worktree config automatically.
The remote-account check is last-write-wins, URL-exact, and cd-triggered
only. The gw-remote-map registry has no per-clone tracking: running gw use <account> anywhere for a given remote overwrites what "the right
account" means for every other clone of that remote — this is intentional,
not a bug. It also matches on the exact remote URL string, so an SSH clone
and an HTTPS clone of the same repo are treated as two unrelated remotes.
And because the check only runs on cd, a shell already sitting in a
mismatched repo when it starts won't warn until you cd away and back.
Commands
gw account add <name>— register an account (prompts for git name/email, GitHub username; can generate a new SSH key for you)gw account list— list registered accountsgw account remove <name>— remove a registered accountgw use <name>— activate an account for the current repogw status/gw whoami— show the active account for the current repogw init <shell>— print the shell prompt snippet forzsh,bash, orfish; add--install(zsh/bashonly) to write and wire it up automatically
Contributing
See CONTRIBUTING.md for dev setup and how to run the tests. Please follow the Code of Conduct. For security issues, see SECURITY.md instead of opening a public issue.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gwitch-0.1.0.tar.gz.
File metadata
- Download URL: gwitch-0.1.0.tar.gz
- Upload date:
- Size: 37.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a29edce51632e4271b37c1b32fdabddba2d5a9a4bb8b3c6dd966b8f87f25a687
|
|
| MD5 |
ec390fdcf5b9b84479e5fe03ff877bda
|
|
| BLAKE2b-256 |
977b04eaca9abbbb36c7702455b4b315bd838885509ca560336b654971f9357f
|
Provenance
The following attestation bundles were made for gwitch-0.1.0.tar.gz:
Publisher:
publish.yml on isamrish/gwitch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gwitch-0.1.0.tar.gz -
Subject digest:
a29edce51632e4271b37c1b32fdabddba2d5a9a4bb8b3c6dd966b8f87f25a687 - Sigstore transparency entry: 2746755444
- Sigstore integration time:
-
Permalink:
isamrish/gwitch@8e36fb1b4744a4fea7c19b33feab5d4bb5bb1951 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/isamrish
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8e36fb1b4744a4fea7c19b33feab5d4bb5bb1951 -
Trigger Event:
release
-
Statement type:
File details
Details for the file gwitch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gwitch-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c2fe8b8cf74fbcdeac5c29888bf7aefbc2f17e00f6a217789802e461f6d8954
|
|
| MD5 |
9322710725ef253e097ba9f60a977b17
|
|
| BLAKE2b-256 |
80bb9edbf444a5cb517cae3742c90bbc6265ac8e29bebb5c5382ce1c53060730
|
Provenance
The following attestation bundles were made for gwitch-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on isamrish/gwitch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gwitch-0.1.0-py3-none-any.whl -
Subject digest:
8c2fe8b8cf74fbcdeac5c29888bf7aefbc2f17e00f6a217789802e461f6d8954 - Sigstore transparency entry: 2746755470
- Sigstore integration time:
-
Permalink:
isamrish/gwitch@8e36fb1b4744a4fea7c19b33feab5d4bb5bb1951 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/isamrish
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@8e36fb1b4744a4fea7c19b33feab5d4bb5bb1951 -
Trigger Event:
release
-
Statement type: