Another option is to write a small script to make core.sshCommand
a bit smarter - check if the current working directory has a specific SSH key configured and if so use it, otherwise - rely on the standard SSH key resolution.
Here is my first version:
#!/bin/bash
key="$(git config ssh.key)"
if [ -n "$key" ]; then
ssh -o IdentitiesOnly=yes -i "$key" "$@"
else
ssh "$@"
fi
Then set it up as the global git SSH command:
chmod 755 ~/.local/bin/git-ssh-command
git config --global core.sshCommand ~/.local/bin/git-ssh-command
(~/.local/bin
is the current standard for "place user scripts here" on SystemD operating systems)
After you set this up, you can configure any repository to use a specific SSH key by setting the configuration option ssh.key
:
git config --local ssh.key ~/.ssh/my-non-default-private-key
Additional Optional Tricks
- Set the global
ssh.key
to have a "default fallback to non-default SSH key" or something.
- As git executes
core.sshCommand
in the root directory of the repository, your custom git-ssh-command
can look at that and have some heuristics about directory names. This can be done in the else
section so heuristics only kick in if there is no specific key in ssh.key
.
- You can add
git remote -v
check to add heuristics based on the the remotes, like in Eike's script
- If you want to look at the repository remotes but have multiple remotes that need different keys, you can add
remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"
at the beginning of the script to resolve the remote being operated on - and check against that ($remote
would look like the middle column in git remote -v
output).
Update:
Here's a version of the custom SSH command that looks at the remote URL and does some heuristics - in my case, I have several different identities with the same public git hosting service (one for work, one for personal, etc) and I can select the correct identity by looking at the remote URL (examining the Gitlab group or the Github organization, etc):
#!/bin/bash
while ! [[ "$1" =~ "git@" ]]; do shift; done # git may send ssh options
if [[ "$2" =~ ^git-lfs-authenticate.* ]]; then # reconstruct url for git-lfs
remote="$1:$(awk '{print$2}'<<<"$2")"
else # reconstruct url for standard git commands
remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"
fi
echo "Detected $remote from $@" >&2
key="$(git config ssh.key)"
if [ -n "$key" ]; then # use specified SSH key, if set
ssh -o IdentitiesOnly=yes -i "$key" "$@"
elif [[ "$remote" == git@gitlab.com:my-company* ]]; then # use company id
ssh -o IdentitiesOnly=yes -i ~/.ssh/company-id "$@"
elif [[ "$remote" =~ git@bitbucket.org:.*other-org.* ]]; then # bitbucket has weird urls
ssh -o IdentitiesOnly=yes -i ~/.ssh/custom-org-key "$@"
else # otherwise use whatever the agent has (my personal key)
ssh "$@"
fi