1 Git
Git, everyone’s favorite version control system, was released (checks notes) 19 years ago on April 7th, 2005. That is some time ago.
Currently, every developer uses Git for one or more projects and/or organizations. In modern days, each and every repo/organization has some form of authentication or other requirements to work with it. I have seen some pretty wacky setups to control how Git is being configured in order to streamline developer productivity and security.
And now, I will introduce my wacky solution 😜 for handeling ssh keys for multiple github accounts.
1.1 Basic Structure
The structure I use has the following files:
.gitconfig
.gitconfig_github_personal
~/.ssh/config
1.1.1 .gitconfig
1.1.2 .gitconfig_github_personal
1.1.3 ~/.ssh/config
So far, not too whacky, right? Git uses the .gitconfig
file to configure Git globally, and then only the actions performed in the folder ~/Developer/github_personal/
will use the .gitconfig_github_personal
file. The SSH key is defined in the SSH config and is used solely for GitHub connections.
Now, if you make a commit, the name and email from the .gitconfig_github_personal
are attached to that commit. This is all fun and games, but what if another project requires a Bitbucket or GitLab account? You can create a .gitconfig
file for each service and add the right key settings to the SSH file.
The “fun” starts when there’s a second instance of a GitHub account; now, all of a sudden, you have a collision in the way you handle your SSH keys - they have the same hostname. 😩
1.2 Extending the Structure
lets add a additional gitconfig
for the work github
.gitconfig
.gitconfig_github_personal
.gitconfig_github_work
.ssh/config
1.2.1 .gitconfig
[user]
useConfigOnly = true
[includeIf "gitdir:~/Developer/github_personal/"]
path = ~/.gitconfig_github_personal
[includeIf "gitdir:~/Developer/github_work/"]
path = ~/.gitconfig_github_work
adding one line for the new work directory, this is linked to the new work gitconfig file.
1.2.2 .gitconfig_github_work
[user]
name=work_name
email= work@example.com
[url "git@github.com-work"]
insteadOf = git@github.com
this is where the magic happens, we instruct git to modify the URL it uses to connect to GitHub, and in the SSH config file, we remap this to the correct hostname. The result is that we can clone repositories as normal, and the folder location determines which SSH keys are used. This means that once set up, we can get on with our work instead of fiddling around with SSH keys. Automation wins!
1.2.3 .ssh/config
1.3 Bonus GPG Signing
If you want to be able to sign commits (and get a green checkmark next to your commits) you can extend the above structure to utilize the SSH key for Git commit signing.
1.3.1 .gitconfig
[user]
useConfigOnly = true
[gpg]
format = ssh
[includeIf "gitdir:~/Developer/github_personal/"]
path = ~/.gitconfig_github_personal
[includeIf "gitdir:~/Developer/github_work/"]
path = ~/.gitconfig_github_work
We start with the global Git config and define the GPG format to be SSH.
1.3.2 gitconfig_github_work
[user]
name = work_name
email = work@example.com
signingkey = <your ssh key>
[commit]
gpgsign = true
[url "git@github.com/work"]
insteadOf = git@github.com
Here, I have added the signingkey
option for the user and set the gpgsign
indicator to true
.
Now also add your ssh key as a signing key!
The next time you commit, it is signed with your SSH key 100% automatically and pain-free – how cool is that!!
P.S. You can also attend a GPG signing party but that’s a topic for another time.