Easy way to use multiple GIT accounts with SSH keys from single computer

I’ve been using a single machine for multiple GIT accounts. I would often get stuck when trying to push/pull changes while using wrong SSH keys or creating commits with invalid username and email combinations. The last bit was incredibly annoying as I would have to review commit history and amend all invalid commit messages. 

I do use the GIT command-line client from my Mac, authenticate over SSH with keys. I also use ZSH shell with Oh My ZSH and the excellent Powerlevel10k theme for ZSH.

Researching articles on the Internet, I didn’t find a solution that would work efficiently for me from the command line. As Oh My ZSH is easy to extend (as I found out after reading a bit of documentation), I created my solution. 

Git profile switch in action

The switching functions, git_switch_to_personal and git_switch_to_work perform two tasks:

  1. Switches the files in the .ssh configuration folder to the appropriate SSH keys
  2. Sets up global git configuration with “user.email” and “user.name” parameters.

I also modified ZSH prompt to show me which profile I have set up currently. The same information can be obtained by executing git_what_profile command.

Following are what’s required to get the functionality sorted.

Switching SSH keys and GIT configuration

I created git_switch.zsh file in the ~/.oh-my-zsh/custom/ folder. When a new shell is started, the file is loaded, and new functions become available. 

git_switch_to_work() {
  rm -rf ~/.ssh/personal ~/.ssh/work && rm -rf ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
  cp ~/.ssh/id_rsa.work ~/.ssh/id_rsa && cp ~/.ssh/id_rsa.work.pub ~/.ssh/id_rsa.pub
  git config --global user.email "greg.gigon@work-email.com" && git config --global user.name "greggigon-work"
  touch ~/.ssh/work
}


git_switch_to_personal() {
  rm -rf ~/.ssh/personal ~/.ssh/work && rm -rf ~/.ssh/id_rsa ~/.ssh/id_rsa.pub
  cp ~/.ssh/id_rsa.personal ~/.ssh/id_rsa && cp ~/.ssh/id_rsa.personal.pub ~/.ssh/id_rsa.pub
  git config --global user.email "greg.gigon@personal-email.com" && git config --global user.name "greggigon"
  touch ~/.ssh/personal
}

git_what_profile() {
  if test -f ~/.ssh/personal; then
    echo personal
  else
    echo work
  fi
}

The functions assume that I have two pairs of SSH keys in the ~/.ssh/ folder, one with keys I use for authenticating with personal GIT account and second for authenticating with work GIT account. 

Content of the ~/.ssh/ folder

The function removes the default SSH keys and copies the selected as defaults, id_rsa and id_rsa.pub. Also, functions create empty files, which indicate the active profile.

Adding GIT profile information to the ZSH prompt

To make permanent changes to the prompt, I had to edit ~/.p10k.zsh file.

First, I created the function with the following content:

function prompt_my_git_profile(){
    if test -f ~/.ssh/personal; then
      p10k segment -s PERSONAL -f green -t "personal"
    else
      p10k segment -s WORK -f red -t "work"
    fi
  }

The function checks for the existence of the files indicating the active profile. The file contains an example prompt function; a great to put the newly created function. 

I also had to add the element to the prompt by modifying POWERLEVEL9K_LEFT_PROMPT_ELEMENTS variable (at the top of the file). 

# The list of segments shown on the left. Fill it with the most important segments.

  typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(
      # =========================[ Line #1 ]=========================
      os_icon                 # os identifier
      dir                     # current directory
      my_git_profile
      vcs                     # git status
      # =========================[ Line #2 ]=========================
      newline
      # prompt_char           # prompt symbol
  ) "

Note that the function is called prompt_my_git_profile but when adding it as one of the elements, I had to drop the prompt_ prefix and only use the my_git_profile in the name.

You can adapt the functions to work with more than two profiles.

Enjoy the simple hack.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s