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:
  1. Contributing to one repository.
  2. Contributing to multiple repositories.
  3. Contributing to multiple repositories over multiple organizations.
  4. 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 1.1 step 1.2 step 1.3
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 2
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:
  1. Use the default key for the current user. This is usually ~/.ssh/id_rsa for RSA keys.
  2. (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
    
                
$ git rev-parse --short HEAD
1597778