Git: working with multiple accounts
Written: 11/8/2023
Knowing how to work with git is an essential skill for modern software
development. When people start their careers working with software, they
usually have to work a Version Control System (VCS), git being the go-to
tool nowadays.
Usually, the complexity of the developers workflow increases over the time
in their careers, including their git workflow. The workflow goes something
like this:
- Contributing to one repository.
- Contributing to multiple repositories.
- Contributing to multiple repositories over multiple organizations.
- maybe there is more?
Very recently i had to work on multiple projects, all of which were hosted
on GitHub. However, each project belongs to a different company which
provided me with their own GitHub credentials. This caused problems for me
when trying to work with multiple repositories that belong to the different
companies.
The Problem
Git provides us with two protocols for cloning repositories. HTTP and SSH.
Assume that we want to clone a random private repository from the first time
in a system:
$ git clone https://github.com/random_user/random_repo
Username for 'https://github.com': <enter your username>
Password for 'https://[email protected]': <enter your password>
remote: Enumerating objects: 291, done.
remote: Counting objects: 100% (291/291), done.
remote: Compressing objects: 100% (195/195), done.
remote: Total 291 (delta 163), reused 207 (delta 79), pack-reused 0
Receiving objects: 100% (291/291), 267.54 KiB | 1.59 MiB/s, done.
Resolving deltas: 100% (163/163), done.
Regardless of your credentials helper, Git would reuse your the same
credentials for the same domain name, in this case, github.com This would
give use trouble if we would want to use multiple accounts within the same
domain.
The solution
It turns out, the solution was within the protocols. I had to ditch the
HTTPS protocol for SSH to make the multiple-account setup work. Most
probably, you are using HTTP protocol to manage your remotes, you can verify
this yourself by running this command within your repository:
$ git remote -v
# Notice the http protocol
origin https://github.com/repository.git (fetch)
origin https://github.com/repository.git (push)
This setup just doesn't work for what we want to acheive.
Creating up SSH keys
You will need to generate N ssh key pairs (private/public), where N is the
number of different git accounts that you will have within the same host
(GitHub in my case). For that, you can use the command `ssh-keygen`. Repeat
this process for all the keys that you want to create.
#Generate an key of type RSA, with the size of 4096 bits.
$ ssh-keygen -b 4096 -t rsa -C "Any comment for your reference"
Generating public/private rsa key pair.
# Set the filename based on what it's intended for
Enter file in which to save the key (/home/alhaddar/.ssh/id_rsa): /home/alhaddar/.ssh/id_rsa_org1
For each key that you create, you will have a private and a public key. For
the example above, it will be:
- /home/alhaddar/.ssh/id_rsa_org1 (Private Key)
- /home/alhaddar/.ssh/id_rsa_org1.pub (Public Key)
Note: the public key is derived from the private key. That is, you can
generate the public key at any moment, given the private key. Git host providers would authenticate the SSH clients by mapping the SSH
client identity (which is defined by the public key) to exactly one user.
The relation looks something like this:
public_key | user_id |
pk1 | user1 |
pk2 | user2 |
Based on this, we can login GitHub for example, and add our public key to
the logged-in user.
Step 1: Go to the settings Step 2: Copy your public key and paste it # This is my public key. You can ger yours by using the command:
cat /home/alhaddar/.ssh/id_rsa_org1.pub
ssh-rsa AAAAB3NzaC1yc2...
Step 3: Repeat step number 1 and 2 for each account, adding a different
public key for each account, refer to the ssh-keygen above on how to create
public keys.
How does the SSH client know which key to use when cloning?
SSH is smart. It would:
- Use the default key for the current user. This is usually ~/.ssh/id_rsa
for RSA keys.
- (Recommended Setup) Use the
ssh config file ~/.ssh/config. If it doesn't exist, then create it. Mine
looks something like this:
Host personal
HostName github.com
User git
IdentityFile ~/.ssh/my_personal_github_private_key
Host company1
HostName github.com
User git
IdentityFile ~/.ssh/company1_github_private_key
Host company2
HostName github.com
User git
IdentityFile ~/.ssh/company2_github_private_key
When cloning repositories, you can use the "Host" to control which
identity to use.
# This would use our personal identity key
git clone personal:repo_path.git
# This would use our company1 identity key
git clone company1:repo_path.git
# This would use our company2 identity key
git clone company2:repo_path.git