Managing Multiple GitHub Accounts: A Guide for Developers

April 21, 2024

6 mins

In the world of software development, managing multiple GitHub accounts from a single machine is a common challenge, especially for developers who need to juggle between personal and professional projects. This guide provides a step-by-step process to help you configure multiple GitHub accounts on one computer, ensuring that you can commit to different repositories under different identities seamlessly.

Step 1: Generate SSH Keys

The first step in setting up multiple GitHub accounts is to generate SSH keys for each account. SSH keys are used to authenticate your identity when interacting with GitHub repositories securely. To generate an SSH key, follow these steps:

  1. Open your terminal.
  2. Run the following command to generate a new SSH key:
ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/id_work
  1. Repeat the process for your personal account:
ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/id_personal

Step 2: Add SSH Keys to GitHub Accounts

Next, add each SSH key to the corresponding GitHub account.

  1. Copy the public key for your primary account:
cat ~/.ssh/id_work.pub | pbcopy
  1. Log into your primary GitHub account, go to Settings -> SSH and GPG keys -> New SSH key, paste your key, and save it.

Here is the GitHub documentation on adding a new SSH key.

  1. Repeat for your secondary account using id_rsa_secondary.pub.

Step 3: Create SSH Config File

  1. Create a new SSH config file or edit the existing one:
vim ~/.ssh/config
  1. Add the following configuration:
# work account
Host account1.github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_work
  IdentitiesOnly yes
# personal account
Host account2.github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_personal
  IdentitiesOnly yes

This configuration aliases github.com to different hostnames for each account, using different SSH keys.

Step 4: Update Git Configurations

Using includeIf, you can specify different Git configurations for each account based on the directory. I recommend creating a different .gitconfig file for each account and including it conditionally based on the repository path.

I store my work repositories in ~/source/work and personal repositories in ~/source/personal. Here's how you can set up conditional includes:

  1. Create or update the global .gitconfig file ~/.gitconfig:
[includeIf "gitdir:~/source/work/"]
  path = ~/.account1.gitconfig
[includeIf "gitdir:~/source/personal/"]
  path = ~/.account2.gitconfig

You can read more about the includeIf directive and gitdir glob patterns in the Git documentation.

  1. Create separate .gitconfig files for each account:
vim ~/.account1.gitconfig
[user]
  name = Saatvik Arya
  email = [email protected]

vim ~/.account2.gitconfig
[user]
  name = Saatvik Arya
  email = [email protected]

Step 5: Update Remote URLs

Finally, once you have organized your existing repositories into the appropriate directories, update the remote URLs to use the SSH aliases you defined in the SSH config file.

I have created this bash script to update the remote URLs for all repositories in a directory. You can customize it based on your directory structure and remote hostnames.

Update the STORES array with the paths to your work and personal repositories, the REMOTES array with the corresponding remote hostnames, and the CONFIG_FILE variable with the path to your SSH config file.

update-remotes.sh:

#!/bin/bash

# Set the directory path and SSH config file
STORES=("/Users/sarya/source/work" "/Users/sarya/source/personal")
REMOTES=("account1.github.com" "account2.github.com")
CONFIG_FILE=~/.ssh/config

# for each store
for i in "${!STORES[@]}"; do
  # get the store path
  STORE=${STORES[$i]}
  # get the remote host
  REMOTE_HOST=${REMOTES[$i]}
  # Loop through each folder in the directory
  for FOLDER in "$STORE"/*; do
    # echo "Updating remote URL for $FOLDER"
    cd "$FOLDER"

    # check if the folder is a git repository
    if [ ! -d ".git" ]; then
      echo "Skipping $FOLDER"
      continue
    fi

    # set of updated remotes for the repository
    UPDATED_REMOTES=()

    # Get the remote URLs
    while read -r line; do
      # Extract the remote name and URL
      REMOTE_NAME=$(echo $line | awk '{print $1}')
      REMOTE_URL=$(echo $line | awk '{print $2}')

      # Check if the remote URL is not remote host and not already updated
      if [[ $REMOTE_URL != *"$REMOTE_HOST"* ]] && [[ ! " ${UPDATED_REMOTES[@]} " =~ " ${REMOTE_NAME} " ]]; then
        # update remote by replacing github.com with $REMOTE_HOST
        NEW_REMOTE_URL=$(echo $REMOTE_URL | sed "s/github.com/$REMOTE_HOST/g")
        # Update the remote URL
        git remote set-url $REMOTE_NAME $NEW_REMOTE_URL
        echo "Updated remote URL for $REMOTE_NAME to $NEW_REMOTE_URL"
        # Add the remote to the updated remotes
        UPDATED_REMOTES+=($REMOTE_NAME)
      fi
    done < <(git remote -v)
  done
done

Step 6: Verify Configuration

To verify that your setup is working correctly, clone a repository from each account and make a commit to ensure that the correct identity is used.

You can also use the following commands to check the remote URLs and the user configuration for each repository:

# Check remote URLs
git remote -v
# Check user configuration
git config --show-origin --get user.email

Conclusion

The previous script can be used to update remote URLs for all repositories in a directory. For new repositories, you can specify the remote URL when cloning the repository using the SSH alias defined in the SSH config file.

Examples of using new remotes when cloning a repository:

git clone [email protected]:work/project.git

git clone [email protected]:aryasaatvik/blog.git

By following these steps, you can set up and manage multiple GitHub accounts on a single machine effectively. This configuration allows you to work on personal and professional projects seamlessly, ensuring that you commit to different repositories under different identities without any conflicts.

I hope this guide helps you streamline your workflow and manage your GitHub accounts more efficiently. Happy coding!