zsh-plugin-git-user-switch
April 3, 2026 ยท View on GitHub
Safe-by-default GitHub identity switching for zsh.
The plugin coordinates three pieces of state:
- repository git identity
- GitHub SSH routing
- optional GitHub CLI account switching
The default design is Safe & Predictable:
- no global SSH mutation during normal use
- repository remotes are rewritten to per-user SSH host aliases such as
github-work - current state is derived from git config, remotes, and
gh auth status
An opt-in magic mode is still available if you want the older global Host github.com rewrite behavior.
Philosophy
Primary mode: safe
- deterministic, repo-scoped behavior
- no hidden writes to
~/.ssh/config - easy to inspect with
gus statusandgus doctor
Secondary mode: magic
- explicit opt-in with
GUS_MODE=magic - rewrites the
Host github.comblock atomically - creates timestamped backups like
~/.ssh/config.bak.20260331153000
Installation
Source the plugin from your .zshrc.
source /path/to/zsh-plugin-git-user-switch/git-user-switch.plugin.zsh
Configuration
The plugin now uses one source of truth: GUS_USERS.
Default config path:
${XDG_CONFIG_HOME:-$HOME/.config}/git-user-switch/config.zsh
Example:
typeset -gA GUS_USERS
GUS_USERS=(
"personal:key" "~/.ssh/personal"
"personal:email" "personal@example.com"
"personal:name" "Personal User"
"personal:host_alias" "github-personal"
"personal:gh_user" "personal-gh"
"work:key" "~/.ssh/work"
"work:email" "work@example.com"
"work:name" "Work User"
"work:host_alias" "github-work"
"work:gh_user" "work-gh"
)
Fields:
user:key: private SSH key pathuser:email: repogit config user.emailuser:name: repogit config user.nameuser:host_alias: SSH alias used in safe mode remotesuser:gh_user:ghaccount name forgh auth switch --user
Optional environment flags before loading the plugin:
export GUS_MODE=safe
export GUS_AUTO_SWITCH=1
export GUS_VERBOSE=0
export GUS_ENABLE_GH_SWITCH=1
export GUS_CONFIG_FILE="$HOME/.config/git-user-switch/config.zsh"
Legacy associative arrays are still imported for compatibility, but GUS_USERS is the target format.
Safe-Mode SSH Setup
Add one alias per identity to ~/.ssh/config:
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/personal
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/work
In safe mode, gus rewrites repository remotes from git@github.com:owner/repo.git to git@github-work:owner/repo.git or similar.
Commands
gus switch <user>
gus appoint <user>
gus status
gus list
gus doctor
gus help
Compatibility shims still exist:
gus <user>
gus-appoint <user>
Usage
Switch a repository to a configured identity without changing repo git config:
gus switch work
Appoint a user to the current repository:
gus appoint work
Inspect state:
gus status
gus doctor
Auto-Switching
Auto-switch is enabled by default and runs on directory change.
Behavior:
- reads repo-local
user.email - maps it to a configured user
- applies the same switching pipeline quietly
- respects
GUS_AUTO_SWITCH=0 - can be temporarily disabled with
gus lockand re-enabled withgus unlock
Current Implementation Status
Implemented in this refactor pass:
- unified
gussubcommands - safe-mode remote rewriting
- opt-in magic SSH mode with backups
gus status,gus list, andgus doctor- compatibility import for legacy config arrays
- behavior-focused zsh tests for safe and magic modes
The remaining guide files in the repo still need to be rewritten to match the new model.