gitwho

Recipes

Four complete accounts.toml configurations, paste-ready. Each is checked at build time against the same schema the annotated template uses, so a recipe here either parses and matches the tool's own example, or the site does not ship.

Copy the config into ~/.config/gitwho/accounts.toml, replace the placeholder usernames, emails and hosts with your own, then run the secret set commands for whichever tokens it names. Then run gitwho init --write again — an account you have just added has no includeIf rule until you regenerate, so until you do, its repositories keep resolving to your global identity. Finish withgitwho doctor.

Two GitHub accounts: personal and work

A personal GitHub login and a separate work login on the same machine need different commit identities and different tokens, chosen by which repository you are in rather than by whichever account you happened to log into last.

toml
[defaults]
account = "Personal"
gitName = "Your Name"

[[accounts]]
name = "Personal"
provider = "github"
email = "you@example.com"
gitCredential = "GH_TOKEN"
sshKey = "~/.ssh/id_ed25519_personal"
match = ["github.com/your-personal-username/**"]
env = ["GH_TOKEN"]
paths = ["~/src/personal/"]

[[accounts]]
name = "Work"
provider = "github"
email = "you@acme.example.com"
gitName = "Your Name (Acme)"
gitCredential = "GH_TOKEN"
sshKey = "~/.ssh/id_ed25519_work"
match = ["github.com/your-work-username/**"]
env = ["GH_TOKEN"]
paths = ["~/src/work/"]

store the tokens, then regenerate

sh
gitwho secret set Personal GH_TOKEN
gitwho secret set Work GH_TOKEN
gitwho init --write

One GitHub host, two organisations

A personal account plus a work organisation, both on github.com. This is the case includeIf "gitdir:" loses most often: both remotes are github.com, so only the path distinguishes them — and path-based rules break exactly when a repo moves, since nothing ties the rule to the remote it was written for. match runs against host/path, so listing the organisations is enough; no directory layout is implied or required.

toml
[defaults]
account = "Personal"
gitName = "Your Name"

[[accounts]]
name = "Personal"
provider = "github"
email = "you@example.com"
gitCredential = "GH_TOKEN"
sshKey = "~/.ssh/id_ed25519_personal"
match = ["github.com/your-personal-username/**"]
env = ["GH_TOKEN"]
paths = ["~/src/personal/"]

[[accounts]]
name = "Work"
provider = "github"
email = "you@acme.example.com"
gitName = "Your Name (Acme)"
gitCredential = "GH_TOKEN"
match = [
    "github.com/acme-corp/**",
    "github.com/acme-labs/**",
]
env = ["GH_TOKEN"]
paths = ["~/src/work/"]

store the tokens, then regenerate

sh
gitwho secret set Personal GH_TOKEN
gitwho secret set Work GH_TOKEN
gitwho init --write

GitHub plus a self-hosted Gitea or Forgejo

One account over https, one over ssh. An https remote authenticates through the credential helper, which needs a token — but an ssh remote authenticates with a key and involves no token at all for push or pull. The self-hosted account below must not be made to invent one: it carries sshKey and nothing else, and that is a complete, working account, not an unfinished one.

toml
[defaults]
account = "Personal"
gitName = "Your Name"

[[accounts]]
name = "Personal"
provider = "github"
email = "you@example.com"
gitCredential = "GH_TOKEN"
match = ["github.com/your-personal-username/**"]
env = ["GH_TOKEN"]
paths = ["~/src/github/"]

[[accounts]]
name = "SelfHosted"
provider = "gitea"
email = "you@example.net"
sshKey = "~/.ssh/id_ed25519_selfhosted"
match = ["ssh.git.example.net/**"]
paths = ["~/src/selfhosted/"]

store the tokens, then regenerate

sh
gitwho secret set Personal GH_TOKEN
gitwho init --write

Adding a third account

Starting from the two-account config above, here is what changes to add a third: one new [[accounts]] block, nothing else touched. Run gitwho init --write again afterwards — it is idempotent and safe to re-run, and reports ok for every step that already matches, so a second run tells you exactly what changed.

toml
[defaults]
account = "Personal"
gitName = "Your Name"

[[accounts]]
name = "Personal"
provider = "github"
email = "you@example.com"
gitCredential = "GH_TOKEN"
match = ["github.com/your-personal-username/**"]
env = ["GH_TOKEN"]
paths = ["~/src/personal/"]

[[accounts]]
name = "Work"
provider = "github"
email = "you@acme.example.com"
gitName = "Your Name (Acme)"
gitCredential = "GH_TOKEN"
match = ["github.com/acme-corp/**"]
env = ["GH_TOKEN"]
paths = ["~/src/work/"]

# --- New: a third account, self-hosted, ssh only -----------------------------
[[accounts]]
name = "SelfHosted"
provider = "gitea"
email = "you@example.net"
sshKey = "~/.ssh/id_ed25519_selfhosted"
match = ["ssh.git.example.net/**"]
paths = ["~/src/selfhosted/"]

store the tokens, then regenerate

sh
gitwho secret set Personal GH_TOKEN
gitwho secret set Work GH_TOKEN
gitwho init --write

Whichever recipe you started from, the last two steps are the same, in this order.gitwho init --write regenerates the identity rules from the config: it is idempotent, and it is what gives each account its includeIf entry. Skip it after adding an account and that account has no rule at all, so its repositories fall through to your global identity — quietly, and with the wrong name on every commit.

Then gitwho doctor. It is read-only, exits non-zero on problems, and never prints a secret value — so its output is always safe to paste when asking for help. It reports that the store's permissions are intact, that every token the config names is present, and that git's credential helper actually reaches gitwho. It does not compare the generated rules against your config, so it will not tell you that you forgot to regenerate.