My SSH keys are named after email addresses: c@anthonyrisinger.com, c@snap.gs, one file per identity in ~/.ssh. Git’s effective user.email selects the preferred key for an SSH connection as well as the author address for a commit.
The key-selection logic began as a compact core.sshCommand. Expanded with quoted arguments and a regular-file check, its shell body is:
email=$(git config user.email)
id=$HOME/.ssh/$email
if [[ -n $email && -f $id ]]; then
set -- -o IdentitiesOnly=yes -i "$id" "$@"
fi
exec ssh "$@"git config user.email resolves conditional includes before returning the value. If a matching key exists, set -- prepends the SSH options without changing the original argument boundaries. Otherwise the script passes through to ordinary SSH behavior. The nonempty-email and -f checks prevent ~/.ssh/ itself from being mistaken for a key.
When wrapping this body in bash -c, supply a value for $0 after the command string. The host and arguments Git appends then reach $@ instead of the first one being consumed as the script name.
IdentitiesOnly=yes excludes extra identities offered only by an SSH agent. Other IdentityFile entries from SSH configuration remain eligible, so this selects a preferred key rather than enforcing one-key authentication. An exclusive-key policy also needs control of the SSH configuration.
Let the remote choose the email
Conditional includes keyed on the remote URL let identity follow a clone wherever it lives on disk. These patterns include the separator before the organization name:
[includeIf "hasconfig:remote.*.url:**:snap-gs/**"]
path = snap-gs/config
[includeIf "hasconfig:remote.*.url:**/snap-gs/**"]
path = snap-gs/configThe first handles scp-style SSH URLs such as git@github.com:snap-gs/repo. The second handles slash-separated URLs, including HTTPS and ssh://. Without the colon in the first pattern, an organization named other-snap-gs could match too.
Each organization-specific file contains the identity:
[user]
email = c@snap.gsThat one value controls commit authorship and supplies the keyfile name. Two email identities that share a key can use a symlink between their keyfiles.
The URL-based hasconfig form requires Git 2.36 or newer. It replaced the earlier directory-based includes in my dotfiles. The examples above include the argument quoting, file checks, and organization delimiters missing from the original compact form.