System tray app for switching between multiple GitHub accounts with git identity management
Project description
github-account-switcher
A lightweight system tray app for switching between multiple GitHub accounts (gh CLI) with a single click. Each account can carry its own git identity (name + email), which is applied automatically on switch.
Platform support
| Platform | Status |
|---|---|
| Linux (X11, XApp-compatible desktop) | ✓ Supported |
| macOS | Coming soon |
| Windows | Coming soon |
Features
- System tray icon showing the active account's initials
- One-click account switching via
gh auth switch - Per-account git identity (
user.name/user.email) applied on switch - First-run auto-populates config from current
git config --global - Start on login (XDG autostart)
Requirements
- Ubuntu 24.04+ / Debian 12+ (Python 3.12 required)
ghCLI with at least one authenticated account- System packages:
gir1.2-xapp-1.0,python3-gi,python3-gi-cairo
Installation
From a release .deb (recommended)
Download the .deb from the latest release and install with:
sudo apt install ./gh-switcher_<version>_amd64.deb
apt resolves the system package dependencies automatically. After installation, gh-switcher is available on your PATH.
via curl
One-line install — fetches and runs the installer script:
curl -fsSL https://raw.githubusercontent.com/panthrocorp/github-account-switcher/main/install.sh | bash
Installs to ~/.local/share/gh-switcher and links the binary to ~/.local/bin/gh-switcher. Re-running upgrades to the latest release.
via pipx
Requires system GTK/XApp bindings first, then install with --system-site-packages so the venv can access them:
sudo apt-get install -y gir1.2-xapp-1.0 python3-gi python3-gi-cairo
pipx install gh-switcher --system-site-packages
via pip
For users who prefer full control over the install. Because python3-gi and gir1.2-xapp-1.0 are system packages not available on PyPI, a plain pip install gh-switcher will fail at runtime on modern Ubuntu/Debian. Use a venv with --system-site-packages instead:
# System deps (once)
sudo apt-get install -y gir1.2-xapp-1.0 python3-gi python3-gi-cairo
# Create an isolated venv that can see the system GTK bindings
python3 -m venv --system-site-packages ~/.local/share/gh-switcher
~/.local/share/gh-switcher/bin/pip install gh-switcher
ln -sf ~/.local/share/gh-switcher/bin/gh-switcher ~/.local/bin/gh-switcher
From source
# Install system dependencies
sudo apt-get install -y gir1.2-xapp-1.0 python3-gi python3-gi-cairo
# Clone and install
git clone https://github.com/panthrocorp/github-account-switcher.git
cd github-account-switcher
make install
Run it:
.venv/bin/gh-switcher
The venv is created with
--system-site-packagesso the GTK/XApp bindings (system packages) are accessible.
Usage
Launch gh-switcher — the tray icon appears in your system tray. Left-click (or right-click) to open the menu and select an account to switch.
Toggle Start on Login to add or remove the XDG autostart entry (~/.config/autostart/gh-switcher.desktop).
Starting on login
The easiest way is via the tray menu — click Start on Login to toggle it. To do it manually, create the XDG autostart entry:
mkdir -p ~/.config/autostart
cat > ~/.config/autostart/gh-switcher.desktop <<EOF
[Desktop Entry]
Type=Application
Name=gh-switcher
Exec=gh-switcher
Hidden=false
NoDisplay=false
X-GNOME-Autostart-enabled=true
EOF
Remove the file to disable autostart.
Configuration
On first run, ~/.config/gh-switcher/accounts.toml is created automatically. The active account is populated from your current git config --global; other accounts get stub entries to fill in:
[alice]
name = "Alice Smith"
email = "alice@example.com"
[alice-work]
name = "Alice Smith (Work)"
email = "alice@work.example.com (set me)"
Click Configure accounts... in the tray menu to open the file in your default editor.
Using with other git providers (Azure DevOps, GitLab, etc.)
gh-switcher writes git config --global user.name and user.email when you switch accounts. If you also work with repos hosted on other providers (e.g. Azure DevOps, GitLab, Bitbucket), the global identity set by gh-switcher will apply to those repos too.
To keep a separate identity for non-GitHub repos, use git's conditional includes (requires git 2.36+). This lets you scope an identity override by remote URL pattern, so gh-switcher can freely manage the global config without affecting your other repos.
Example: Azure DevOps
Create an identity file:
mkdir -p ~/.config/git
cat > ~/.config/git/ado-identity <<EOF
[user]
name = Your Name
email = your.email@company.com
EOF
Add a conditional include to ~/.gitconfig:
[includeIf "hasconfig:remote.*.url:git@ssh.dev.azure.com:v3/your-org/**"]
path = ~/.config/git/ado-identity
Any repo whose remote matches the pattern will use the identity from ado-identity instead of the global one. You can add multiple includeIf blocks for different providers or organisations.
Example: GitLab
[includeIf "hasconfig:remote.*.url:https://gitlab.com/your-org/**"]
path = ~/.config/git/gitlab-identity
Alternative: directory-based
If you keep provider repos in separate directories, you can scope by path instead:
[includeIf "gitdir:~/repos/work/"]
path = ~/.config/git/work-identity
Development
make lint # ruff check src/ tests/
make format # ruff format src/ tests/
make test # pytest + bats (test-py + test-bash)
make test-py # pytest unit tests only
make test-bash # bats shell tests only (install.sh)
Releasing
Releases are driven by semantic-release via GitHub Actions on push to main. Commit messages must follow the convention:
| Prefix | Release |
|---|---|
fix: |
patch |
feat: |
minor |
breaking: |
major |
Licence
Project details
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 gh_switcher-1.4.0.tar.gz.
File metadata
- Download URL: gh_switcher-1.4.0.tar.gz
- Upload date:
- Size: 126.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bfd15a590db060361e9674489466c9acf7ce07ed68d6676b01d3bf9580e6d370
|
|
| MD5 |
c325e9d72a9c5c835fc83e56659f33ce
|
|
| BLAKE2b-256 |
d8c1cab8f23256075db682c48727814b84e2da2898f44cfb93bf66b1641ea4b0
|
Provenance
The following attestation bundles were made for gh_switcher-1.4.0.tar.gz:
Publisher:
publish.yml on panthrocorp/github-account-switcher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gh_switcher-1.4.0.tar.gz -
Subject digest:
bfd15a590db060361e9674489466c9acf7ce07ed68d6676b01d3bf9580e6d370 - Sigstore transparency entry: 1132701677
- Sigstore integration time:
-
Permalink:
panthrocorp/github-account-switcher@4df1d80fc2d308f8c33ed315ebfe4e75c6264634 -
Branch / Tag:
refs/tags/v1.4.0 - Owner: https://github.com/panthrocorp
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4df1d80fc2d308f8c33ed315ebfe4e75c6264634 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file gh_switcher-1.4.0-py3-none-any.whl.
File metadata
- Download URL: gh_switcher-1.4.0-py3-none-any.whl
- Upload date:
- Size: 15.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
447dc676cb2af1b67b4f96097b4775e2b313150f81915f3257ab7e6a745bafac
|
|
| MD5 |
7c1230d3724203960f4ccfb51d109e07
|
|
| BLAKE2b-256 |
4ea3bea28bf7950d655e7df89eaa96177b702aa249a7eb9370e7688812d6e381
|
Provenance
The following attestation bundles were made for gh_switcher-1.4.0-py3-none-any.whl:
Publisher:
publish.yml on panthrocorp/github-account-switcher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
gh_switcher-1.4.0-py3-none-any.whl -
Subject digest:
447dc676cb2af1b67b4f96097b4775e2b313150f81915f3257ab7e6a745bafac - Sigstore transparency entry: 1132701769
- Sigstore integration time:
-
Permalink:
panthrocorp/github-account-switcher@4df1d80fc2d308f8c33ed315ebfe4e75c6264634 -
Branch / Tag:
refs/tags/v1.4.0 - Owner: https://github.com/panthrocorp
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4df1d80fc2d308f8c33ed315ebfe4e75c6264634 -
Trigger Event:
workflow_dispatch
-
Statement type: