πŸ‘₯ Use multiple git accounts: how not to cry

πŸƒ TL;DR Work locally with multiple git accounts with transparency, using ssh and gitconfig configurations

πŸ”– Introduction

I’m on the train, with the mask that covers half my face (thx covid) and breathing is not so easy.
For god sake’s the train is not full, albeit those few people are making a noise as if we were at the main stage of the zsiget festival. 4 hours left on my journey to come back to my city…

…which best moment to explore a longstanding problem I’ve always avoided?

The problem:

I use 3 different git account on my laptop (2 GitHub, 1 Bitbucket) and I would like to use them (basically clone & commit) with transparency.

🀝 Greetings:

I didn’t do anything (like usual) but only join two great guides found online:

  • Multiple SSH Keys settings for different GitHub account - gist link
  • Multiple git profile - gits link

πŸ”¨ How to

In the examples, we will set up two git accounts: one for work and one for personal projects.
The process is easily scalable up to N accounts.

  1. Create ssh keys for each of your git account.

    # Create the work ssh key, filename: git_work_account
    $ ssh-keygen -t ed25519 -C "work_email@example.com"
    
    # Create the personal ssh key, filename: git_personal_account
    $ ssh-keygen -t ed25519 -C "personal_email@example.com"
    
    # Albeit the prompt tell you the keys will be stored
    # on ~/.ssh/ folder; is there a chance that this is
    # not done and the keys are generated on the current
    # folder, so check it and optionally run:
    # $ cp ./git_personal_account* ~/.ssh/
    # $ cp ./git_work_account* ~/.ssh/
    
    # Start the ssh-agent
    $ eval "$(ssh-agent -s)"
    
    # Add the ssh private keys
    $ ssh-add ~/.ssh/git_personal_account
    $ ssh-add ~/.ssh/git_work_account
    
  2. Add the ssh public key to your version control host.
    πŸ”— Adding a new SSH key to your GitHub account
    πŸ”— Bitbucket Set up an SSH key

  3. Configure the ssh config file.
    πŸ’‘ The Bitbucket account is reported only for information purposes because the “interesting” part is to use multiple accounts toward the same provider.

    $ cd ~/.ssh/
    
    # Create the file config
    $ cat config
    > # Github work account
    > Host github.com
    >     HostName github.com
    >     User git
    >     IdentityFile ~/.ssh/git_work_account
    > 
    > # Github personal account
    > Host github.com-personal-account
    >     HostName github.com
    >     User git
    >     IdentityFile ~/.ssh/git_personal_account
    > 
    > # Example with second Bitbucket work account
    > Host bitbucket.org
    >         HostName bitbucket.org
    >         User git
    >         IdentityFile ~/.ssh/git_work_account
    
  4. Clone the repositories from both accounts
    πŸ’‘ The only different thing from the usual git clone in ssh mode is the use of an appendix after the [github.com](http://github.com) section during the clone

    # Make one folder for each account
    $ mkdir ~/work-projects
    $ mkdir ~/personal-projects
    
    # Clone the work repo
    $ cd ~/work-projects
    $ git clone git@github.com:[USER]/[REPO].git
    
    # Clone the personal repo
    $ cd ~/work-projects
    $ git clone git@github.com-personal-account:[USER]/[REPO].git # [!]
    
  5. Dynamically assign the git username and email, based on the repository main folder

    • ❗Problem: each commit we do for each project share the same git user name and email. This is an unintended behaviour because our goal is to manage the work and personal projects with their respective accounts.
    • πŸ’‘ We will solve this problem by editing the gitconfig file
    # First: create both .gitconfig-[work/personal] file
    $ cat ~/work-projects/.gitconfig-work
    > [user]
    >   name = work-git-name
    >   email = work_email@example.com
    
    $ cat ~/personal-projects/.gitconfig-personal
    > [user]
    >   name = personal-git-name
    >   email = personal_email@example.com
    
    # Then add those files to ~/.gitconfig 
    $ cat ~/.gitconfig
    > ... # [lines skipped] the global git configurations
    > 
    > [includeIf "gitdir:~/work-projects/"]
    >         path = ~/work-projects/.gitconfig-work
    > 
    > [includeIf "gitdir:~/personal-projects/"]
    >         path = ~/personal-projects/.gitconfig-personal
    
    # Check the correct git account is assigned for each folder
    $ cd ~/work-projects/
    $ git config user.name
    > work-git-name
    $ git config user.email
    > work_email@example.com
    
    $ cd ~/personal-projects/
    $ git config user.name
    > personal-git-name
    $ git config user.email
    > personal_email@example.com