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.

Using Atlassian Stash pull requests for mandatory code reviews

During my early years of software development I used to think of Code Reviews as a necessary bureaucratic monster, process designed to stop me from delivering the value and focus on pointing out mistakes.

My outlook at it has changed. There are many benefits of code reviews. Some of them that are more important for me:

  • increases quality of code therefore improves maintenance
  • facilitates sharing of the information and knowledge with fellow developers
  • improves my coding skills thanks to feedback

At RBS we are using Subversion and GIT as our SVC tools. We are using Stash to manage our repositories. Stash has a very useful features that could help setup the code review as a mandatory process, before the code is merged into the main branch. In this post I would like to show you how to set it up and how to use it.

Use case for code reviews

The use case for the Mandatory code review is taken from a real case brought at my work by one of the teams. The team was typical, Technical Lead, Senior Devs and Junior Devs. They wanted to leverage the Code Review goodness for learning.

What the users wanted to do is:

  • allow only specific users to be able to modify code in Master branch of GIT repository
  • allow everyone else on the team to create their local branches and push those branches into remote repository
  • have the ability to raise a code review of changes made on a user branch before merging the changes into the Master
  • have the ability to comment, decline the changes
  • once the changes were accepted to allow anyone with enough permissions to merge the code

You might notice similarity in that process to the one that is quite common in the Open Source community and was championed by GitHub, called Pull-Request (on a side note, this site is great EpicPullRequests).

Preparing repository for code reviews (or for Pull Requests)

First thing to do would be to make sure that all the people in your team are Contributors to a project. I have a group of users in Stash called superheroes. I need to set them as a Contributors on my project.

My user group Superheroes setup in Stash
My user group Superheroes setup in Stash

Project level permission settings
Project level permission settings

What I’ve done above means that everyone superhero in the group would be able to contribute to the project. The next step will restrict the changes on Master branch and allow it only for a specific user (in our case, Superman).

Adding branch permissions for Superman to a Master
Adding branch permissions for Superman to a Master

The above action will result in only Superman being able to make any changes on Master.

Batman trying to push into Superman repository and fails
Batman trying to push into Superman repository and fails

What would Batman do?

For Batman (the user that is restricted on Master but allowed on Project level) to be able to work he needs to work on a branch, push that branch into Stash and create a merge request (Pull request).

Batman working on a Batmobile feature on it's own branch. Pushing to remote repository after the work is done
Batman working on a Batmobile feature on it’s own branch. Pushing to remote repository after the work is done

Creating the Pull Request

When Batman finished working on the feature he would like to Batmobile to become mainstream and be adopted by all Superheroes. What he needs to do is to merge hist feature into the Master branch. We know already that he cannot do it as someone need to review his changes. In our case it’s the Superman.

Batman creates a Pull Request.

Batman Creates a pull request for his changes to be merged into Master. The selected reviewer is Superman
Batman Creates a pull request for his changes to be merged into Master. The selected reviewer is Superman

What Superman will see once he is logged into Stash he can review the Pull Request, approve them, decline, comment, etc.

Screen that Superman see when he reviews Barman's pull request
Screen that Superman see when he reviews Barman’s pull request

Once the request is approved, Superman or anyone else with the permissions to modify Master can merge it.

Possibly worth to mention the fact that it is possible for anyone to review the changes as it is possible for Batman to request anyone to be the reviewer, however, only the users with enough privileges will be able to merge the changes.

Superheroes conclusion

The above setup leverages the feature of Branch Permissions in Stash. Anyone who would like for changes to be merged into the Master branch will need to go through Code Review.

Wishing you many happy reviews and much more learning.