Commands
Every gitswitch command and flag
gitswitch --help groups commands the same way this page does.
| Identity | add switch list remove current init |
| Session Isolation | pin unpin guard xcode shell uninstall doctor |
| Channels | version upgrade beta stable |
| Extras | login skills reauthor pacman |
Plus gitswitch with no arguments, and gitswitch <nickname> as a shortcut.
gitswitch — the interactive UI
gitswitchThree tabs — Accounts, Utilities, Settings — reachable with 1 2 3, tab / shift+tab, or a mouse click.
| Key | |
|---|---|
↑ ↓ / k j | Move |
enter | Switch to this account (globally) |
p | Pin/unpin this account to the current repo — only shown inside a repo |
a | Add an account |
e | Edit — ctrl+d inside the form deletes |
v | Toggle the second column between email and GitHub username |
c | Cycle color theme (12 of them) |
u | Upgrade — only appears when a newer version exists |
? | CLI cheat sheet |
1 2 3 / tab | Switch tab |
q / ctrl+c | Quit |
The mouse works throughout: hover moves focus, clicks select and toggle, the scroll wheel moves through lists.
Utilities tab — three toggles: Shell Integration, Session Isolation, HTTPS Credential Helper.
Settings tab — theme, config file location (opens it in $EDITOR), and the gs shell alias (rename with e, toggle with enter).
First launch on a machine with no profiles yet checks for git/gh and offers to install whichever's missing, then runs a short onboarding wizard, which scans your gh logins and ~/.ssh/ keys and offers to import them.
gitswitch <nickname> — quick switch
gitswitch work✓ Switched to 'work' — Alice Smith <alice@company.com>Identical to gitswitch switch work. Exits non-zero if the nickname doesn't exist.
Identity
add
gitswitch add <nickname> <user-name> <email> [flags]| Argument | |
|---|---|
nickname | Short label — work, oss, client-a. Must be unique. Never written to git config. |
user-name | Value for user.name. Quote it if it has spaces. |
email | Value for user.email. |
| Flag | |
|---|---|
--ssh-key <path> | Private key path. Sets core.sshCommand to ssh -i <path> -o IdentitiesOnly=yes on switch. |
--sign-key <key> | GPG key ID or an SSH key. Sets user.signingkey, plus gpg.format=ssh for SSH keys. |
--gh-user <username> | GitHub username. Runs gh auth switch --user <username> on switch (best-effort). |
gitswitch add personal "Alice Smith" alice@gmail.com
gitswitch add work "Alice Smith" alice@company.com \
--ssh-key ~/.ssh/id_work \
--sign-key ABCD1234EF567890 \
--gh-user alice-corpPrefer not typing all that? gitswitch login fills it in from GitHub.
switch
gitswitch switch <nickname>Same as gitswitch <nickname>. See Commit Identity for exactly what gets written.
list
gitswitch list [--json]✓ personal Alice Smith <alice@gmail.com>
work Alice Smith <alice@company.com>✓ marks your active global account.
current
gitswitch current [--json | --short | --prompt]work — Alice Smith <alice@company.com> (pinned to this repo)
HTTPS credential helper: activeThe suffix names the scope: nothing for global, (pinned to this repo), or (this terminal's session). If a pin exists but Session Isolation is off, it says so.
Prints No active profile if nothing has been applied yet.
| Flag | |
|---|---|
--json | {nickname, user_name, email, scope, gh_user, ssh_key, credential_helper_active} |
--short | nickname<TAB>email, with the scope marker on the nickname (work●). For Starship. |
--prompt | nickname<TAB>color<TAB>marker — theme color as an ANSI 256 index. For prompt functions. |
remove
gitswitch remove <nickname>Deletes the account. Does not revert git config that was applied while it was active, and doesn't revoke anything on GitHub. Any history entries under that nickname stay behind harmlessly.
init
gitswitch initImports your current --global user.name / user.email as an account named default. Runs automatically on first use if you have no accounts.
Session Isolation
pin
gitswitch pin [nickname]Writes the account's full identity into this repo's local git config — user.name, user.email, user.signingkey/gpg.format, core.sshCommand. Your global identity is untouched.
With no nickname, it adopts the repo's existing local user.email and matches it to a stored account.
Turns Session Isolation on automatically if it was off, since a pin can't take effect without it. Must be run inside a git repo.
unpin
gitswitch unpinRemoves those keys from the repo's local config; the repo falls back to your global identity. Must be run inside a git repo.
guard
Refuses a commit whose author doesn't match the right gitswitch profile before it enters history. Installs a global pre-commit hook (git config --global core.hooksPath) that chains into any existing global hooks path and each repo's own hooks, so Husky, lefthook and pre-commit keep working.
gitswitch guard enable # install the hook
gitswitch guard disable # remove it (restores a previous core.hooksPath)
gitswitch guard status # hook state + whether this repo would pass (--json supported)
gitswitch guard check # what the hook runsA commit is blocked when there is no user.email, the email matches no profile, the repo is pinned to a different profile, or (for unpinned repos) gitswitch has learned a different profile for it. With no profiles yet, everything is allowed.
xcode (early)
Keeps Xcode's own GitHub accounts (Xcode → Settings → Accounts) in step with gitswitch. Xcode stores tokens in a keychain group only Apple's processes can write, so each account is still added to Xcode once — gitswitch makes that one paste and then manages which account Xcode picks. Commit authorship needs nothing: Xcode already reads git config.
gitswitch xcode status # Xcode's accounts vs your profiles (--json supported)
gitswitch xcode add [nickname] # copy the profile's gh token to the clipboard (--pat: open GitHub's token page)
gitswitch xcode sync [nickname] # make that profile's account Xcode's default (--dry-run to preview)
gitswitch xcode bind [nickname] # embed the username in this repo's https remotes
gitswitch xcode unbind
gitswitch xcode enable|disable # run sync on every switch, bind/unbind on pin/unpinXcode matches a remote to an account by a username in the URL, then the repo owner, and otherwise uses the first account listed. sync reorders that list; bind pins a single repo regardless of order. SSH remotes are never rewritten. Xcode reads its accounts at launch, so restart it after a change.
shell
gitswitch shell [flags]Interactive wizard with three steps, each skippable:
- Shell integration — prompt segment, nudge on
cd, tab completion,gsalias - HTTPS credential routing — right token per repo on push
- Session Isolation — right
ghaccount per repo, and working pins
| Flag | |
|---|---|
--shell <zsh|bash|fish> | Override shell detection. Also skips the wizard. |
--yes / -y | Accept all defaults, no prompts. For scripts and CI. |
--https | Register the HTTPS credential helper. Default true; prompted interactively when omitted. |
Safe to re-run — everything lives between # gitswitch markers and gets replaced in place, never duplicated. Re-run it after an upgrade to pick up an improved hook, or to repair credential-helper ordering.
uninstall
gitswitch uninstall [--shell <zsh|bash|fish>]Removes the shell integration block (or oh-my-zsh plugin), unregisters the HTTPS credential helper, and removes the gh wrapper — whichever were installed. Your accounts are left alone. Reload your shell to finish.
doctor
gitswitch doctor [--json] ✓ git 2.50.1
✓ gh 2.95.0
✓ HTTPS pushes routed by gitswitch
✓ Session Isolation active (bare `gh` commands resolve per-repo)The HTTPS check is the interesting one — git asks credential helpers in config order and takes the first answer, so another tool's helper registered ahead of gitswitch means gitswitch never gets asked:
✗ HTTPS pushes answered by another helper before gitswitch:
credential.https://github.com.helper → !/opt/homebrew/bin/gh auth git-credential
pushes may use the wrong account — run: gitswitch shellgitswitch shell fixes the order without removing the other helper. See HTTPS Push Routing.
Channels
version
gitswitch versionPrints your version and checks for a newer one (cached 24h).
upgrade
gitswitch upgradeInstalls the latest release. On a Homebrew install it tells you to run brew upgrade gitswitch instead.
beta / stable
gitswitch beta # canary pre-releases
gitswitch stable # back to normalBoth confirm first and never touch ~/.config/gitswitch/. See Versions & Release Channels.
Extras
login
gitswitch login [--profile <nickname>] [--host <hostname>]Delegates to gh auth login (the real GitHub CLI's own login command) to authenticate with GitHub, then reads the resulting account back via gh. Creates an account with your name, email, and username filled in — no custom OAuth app or separate registration step needed since gh owns the account the moment it authenticates. Re-running it on an existing account refreshes your login and keeps your SSH/signing keys. See Connecting Accounts.
skills
gitswitch skills [--scope user|project] [--offline] [--check] [--update]Installs or updates the gitswitch skill, embedded in the binary. Tries skills.sh first (works with Claude Code, Cursor, Codex, and more); falls back to installing directly for Claude Code and the shared .agents/skills convention when --offline is passed or npx isn't available. user → ~/.claude/skills/, ~/.agents/skills/ (default), project → .claude/skills/, .agents/skills/.
Use --check to verify whether installed skill files match the current binary, or --update to rewrite all installed skill files. gitswitch upgrade updates installed skills automatically.
reauthor
gitswitch reauthor <base> --to <nickname> [--from <email>] [--push] [--yes]Rewrites author and committer on commits between <base> and HEAD. <base> is a commit-ish or a bare number meaning "the last N commits".
| Flag | |
|---|---|
--to <nickname> | Required. The account to attribute to. |
--from <email> | Only rewrite commits currently authored by this email. |
--push | Force-push (--force-with-lease) afterwards. |
--yes / -y | No confirmations — for scripts and agents. |
This rewrites history. Full context in AI Coding Agents.
pacman
gitswitch pacmanToggles arcade mode on or off for every future launch. No, we won't explain it here.
record / recommend
Used by the shell hook. You rarely run these by hand.
gitswitch record [--path <dir>] # count the active account for this repo
gitswitch recommend [--path <dir>] # print the recommended account, if anyrecommend exits 0 and prints nickname<TAB>name<TAB>email when there's a recommendation, 1 silently when there isn't. See Pins & Identity Awareness.
Exit codes
0 | Success |
1 | Something went wrong — account not found, git missing, not in a repo |
gitswitch recommend exiting 1 is normal and expected: it means "nothing to suggest".
Where things are stored
~/.config/gitswitch/config.yaml | Your accounts |
~/.config/gitswitch/config.json | UI preferences — theme, alias, arcade high score |
~/.config/gitswitch/history.json | Per-repo usage counts and pin records |
Full detail in Configuration.