Switching Github accounts
17 October, 2023
After using my personal account for over a decade, I recently created a new GitHub account for work. This helps me keep the two identities separate and the attribution remains linked to the correct corresponding account.
Transitioning the organizations and repositories was fairly straight-forward. However, I encountered difficulties once I tried to run git pull
in one of the work repositories. Later that day, I received a message from my team that one of the GitHub Action was failing. This was because the action was using a token which was generated from my personal account. I generated a new token using the work account and it started working.
The larger issue to address was how to push or pull to repositories linked to two different GitHub accounts. I needed to use two different authentication identity providers. Until now, I was using the GitHub CLI for multiple purposes including authentication, but now it looked like I’d need to switch back to using ssh keys.
I generated two keys for personal and work use:
ssh-keygen -t ed25519 -C "[email protected]" -f $HOME/.ssh/personal -P ""
ssh-keygen -t ed25519 -C "[email protected]" -f $HOME/.ssh/work -P ""
and then configured the $HOME/.ssh/config
file to specify the ssh key based on the Host
Host skippednote.github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/personal
Host axelerant.github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/work
This works great for repositories like github.com/skippednote/dotfiles
or github.com/axelerant/create-drupal-theme
. Since, GitHub doesn’t have groups, at work we have numerous organizations under our GitHub enterprise like github.com/axelerant-project-dalek
or github.com/axelerant-project-kahn
. To address this, I’d have to keep updating the config file to add new Host
’s. Despite the overhead, this fix works. However, it didn’t seem like a satisfactory solution to me.
All my repositories can be found in the code
directory under $HOME
. This directory is further divided into two sections: ~/code/personal
and ~/code/work
. This segregation allows me to execute certain commands based on which directory I’m currently in.
GitHub CLI allows us to authenticate interactively or using a token. The token can be read from a file using:
gh auth login --from-token < FILE_NAME.txt
If a GH_TOKEN
environment variable exists, we don’t need have a separate file and this is where direnv
would help us.
I generated two different Personal Access Token from my personal and work accounts with repo
and read:org
scopes assigned.
With two PAT tokens from two different accounts, I created .envrc
files under work
and personal
directories.
touch ~/code/{work,personal}/.envrc
These files were populated with the following content
export GH_TOKEN=[WORK/PERSONAL_GITHUB_TOKEN_VALUE]
export GIT_SSH_COMMAND="ssh -i ~/.ssh/[either `personal` or `work`]"
gh auth login --hostname=github.com
Now every time I cd
into a directory under work
or personal
direnv would use the specified token in the .envrc
and log me into the corresponding GitHub account.
Using SSH everywhere
The last update to make everything work smoothly is to use ssh
instead of https
. To make this update globally I updated my global gitconfig
file.
git config --global url.ssh://[email protected]/.insteadOf https://github.com/
Switching Email Address
Regardless of which repository I committing to I was seeing my personal email next to my name. A simple work around for this is to override the git author email using direnv
. Updating the .envrc
to include the work and personal emails resolved this.
export GH_TOKEN=[WORK/PERSONAL_GITHUB_TOKEN_VALUE]
export GIT_AUTHOR_EMAIL=[WORK/PERSONAL_EMAIL_ADDRESS]
export GIT_SSH_COMMAND="ssh -i ~/.ssh/[either `personal` or `work`]"
gh auth login --hostname=github.com
Updates
I noticed that I was seeing both my work and personal accounts showing up on all my commits.
This happens because your commit has properties for the author
and the committer
. To override this, I had to set an additional environment variable for the committer: [email protected]
.