Programmer Diaries: S01E01 – Multiple GitHub Keys
As a programmer, every couple weeks I have to get into some sysadmin tasks, like creating a SSL certificate, pushing a new build to PyPi, setting password-protected directories in apache, using the same server for two GitHub repositories, etc. Nothing fancy, you might say, but it always take me some time to remember “how it was done.” Since at Tivix we love to share our knowledge, I’ve decided to create this Programmer Diaries blogpost series.
Multiple GitHub deploy keys on same server
So you have your Linux testing server where you want to put many GitHub projects on the same system user account? You will probably get Error: Key already in use. This error occurs when you try to add a key to an account, and that key has already been added to another account or repository. Do we have to create a new Linux user and assign a new key? Not really. We can create multiple keys for same Linux user with one small SSH configuration file and still use git pull
or git push
without a problem.
- Create SSH keys for your projects and change the keyname to something more specific:
ssh-keygen -t rsa -C "Project 1" Generating public/private rsa key pair. Enter file in which to save the key (/Users/xxx/.ssh/id_rsa): project_1 Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in test. Your public key has been saved in project_1.pub. ssh-keygen -t rsa -C "Project 2" Generating public/private rsa key pair. Enter file in which to save the key (/Users/xxx/.ssh/id_rsa): project_2 Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in test. Your public key has been saved in project_2.pub. ...
- Copy the corresponding public keys to the Deploy Key section of your GitHub repository.
- Set up the SSH config file, by editing ~/.ssh/config:
nano ~/.ssh/config
and add these values:
Host project_1 GitHub.com Hostname GitHub.com IdentityFile /home/xxx/.ssh/project_1 Host project_2 GitHub.com Hostname GitHub.com IdentityFile /home/xxx/.ssh/project_2
That’s all! To clone your repository using proper SSH keys just replace github.com with the new host name, for example,
git clone git@github.com:your_account/project_1.git git clone git@github.com:your_account/project_2.git
should look like this:
git clone git@project_1:your_account/project_1.git git clone git@project_2:your_account/project_2.git
From now on, you can use all git commands like git pull
or git push
without providing any extra parameters!
Bonus: Incomprehensible Git conflicts – diff3
We all know Git is awesome. But every version control system has conflicts. Sometimes it’s really hard to determine what was really changed and how to resolve it.
Example of git diff output:
<<<<<<< HEAD report = user.generate_report(full=False) ======= report = user.prepare_report(full=True) >>>>>>> change-branch
Looking at this conflict we are unable to say what exactly each branch changed. Moreover we have no idea what it’s intent was.
To resolve this issue let’s use diff3. It’s easy like running one command:
git config --global merge.conflictstyle diff3
Now let’s run git diff once again:
<<<<<<< HEAD report = user.generate_report(full=False) ||||||| merged common ancestor report = user.prepare_report(full=False) ======= report = user.prepare_report(full=True) >>>>>>> change-branch
New lines comes up called common ancestor. Now conflict resolution workflow looks like:
- Use common ancestor branch as starting point
- Compare ancestor branch with other branches, HEAD and change-branch in our case
- HEAD intent is to change function name from
prepare_report
togenerate_report
- change-branch intent is to change default parameter
full
from False to True - Combine intent of both and merge changes
In our case, after merging changes we receive:
report = user.generate_report(full=True)
That’s it! We resolved our conflict!
See you on the next episode of Programmer Diaries!