Skip to content

Instantly share code, notes, and snippets.

@pil0u
Last active January 7, 2024 15:35
Show Gist options
  • Save pil0u/95a97ebf10d47a0f7d62395d6a837fea to your computer and use it in GitHub Desktop.
Save pil0u/95a97ebf10d47a0f7d62395d6a837fea to your computer and use it in GitHub Desktop.

How to manage two GitHub accounts on a Mac

For some reason, you need to manage two different GitHub accounts on your machine - e.g. personal and work.

After a thorough research online along with a test-and-learn approach, the following steps were successful for me.

Assumptions

  • For the sake of this guide, both accounts are called foobar and waldo.

  • I assume you work with GitHub with SSH. If not, you will.

  • I somehow assume that one GitHub account is already set up on the machine and you want to add a second one.

  • I also assume this folder structure, but obviously another similar would work:

    /Users/You/             <-- This is ~/
    └── GitHub/
        ├── foobar/
        │   ├── project-toto
        │   └── project-titi
        └── waldo/
            ├── project-tata
            └── project-tutu
    
  • I assume that foobar acts as the default account, i.e. the one you use the most.

1. Remove existing credentials for Apple's Keychain Access

You might have stored GitHub-related credentials (passwords, SSH key passphrases) into Apple's Keychain. I figured this added an extra layer of complexity, unecessarily.

This command will tell you if you where osxkeychain is used and configured:

$ git config --get-all --show-origin credential.helper

For me, the sole appearance was in /Library/Developer/CommandLineTools/usr/share/git-core/gitconfig
To stop using osxkeychain, using your favourite text editor, comment out the lines in the file(s).

Additonally, you can remove the credentials from the Keychain Access app.

  1. Launch the Keychain Access app
  2. Search for github.com in the top-right search bar
  3. Delete the entries that appear

Note

You can always re-add the credentials to the Keychain Access app later, if you want to.

2. Generate one SSH key for each GitHub account

(optional) You do not have an SSH key for the first GitHub account

Generate the first key:

$ ssh-keygen -t ed25519 -C "foobar" -f "/Users/You/.ssh/id_ed25519"

The -t flag specifies the algorithm, ed25519 being the recommended one.
The -C flag is the comment used to describe the key.
The -f flag is the file name of the key.

When prompted, create the passphrase for the key.

...
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/You/.ssh/id_ed25519
Your public key has been saved in /Users/You/.ssh/id_ed25519.pub
...

Generate the second SSH key

$ ssh-keygen -t ed25519 -C "waldo" -f "/Users/You/.ssh/id_ed25519_alt"

When prompted, create the passphrase for the key.

This command will generate two files in the ~/.ssh/ folder:

  • id_ed25519_alt - the private key
  • id_ed25519_alt.pub - the public key

Register both keys to the authentication agent

I assume your setup is simple enough that you don't have a thousand SSH keys lying around.

To make sure of that, run:

$ ssh-add -l

If you get The agent has no identities. then you're good to go.

If not, you can remove all keys from the authentication agent by running:

$ ssh-add -D

Finally, add both keys to the authentication agent:

$ ssh-add ~/.ssh/id_ed25519
$ ssh-add ~/.ssh/id_ed25519_alt

Note

The first key you add will act as the default one.

3. Add public keys to each GitHub account

The following steps have to be followed for each GitHub account, so be careful to use the right key for the right account.

Example for foobar:

  1. Copy the content of the corresponding public key file:
    $ cat ~/.ssh/id_ed25519.pub
  2. Go to https://github.com/settings/ssh/new to add a new SSH key on GitHub
  3. For the title, choose something that will help you identify the machine, e.g. my-macbook
  4. Paste the content of the public key file into the Key field
  5. Hit the Add SSH key button

4. Create a config file in the ~/.ssh/ folder

This file will tell SSH which key to use for which GitHub account.

$ touch ~/.ssh/config

Add the following content to the file:

# foobar (default)
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519

# waldo
Host waldo-github.com                   # This is an alias, use any
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_alt    # Use the second key

Important

By specifying a different Host alias, any future remote URL will have to use that name instead of @github.com.
In particular:

$ git clone git@github.com:waldo/project-tutu.git

should now be written:

$ git clone git@waldo-github.com:waldo/project-tutu.git

...or should it?

5. Setup .gitconfig files

You might be familiar with the git config --global command, which sets up the ~/.gitconfig file.

We are going to edit/create two files:

/Users/You/
├── .gitconfig            <-- HERE
└── GitHub/
    ├── foobar/
    │   ├── project-toto
    │   └── project-titi
    └── waldo/
        ├──.gitconfig     <-- AND HERE
        ├── project-tata
        └── project-tutu

Let's break them down.

# /Users/You/.gitconfig

[user]
  name = foobar
  email = foobar@example.com

[includeif "gitdir:~/GitHub/waldo/"]
  path = ~/GitHub/waldo/.gitconfig

The [user] section corresponds the default user across all ~/, in this case foobar. Again, this default account should correspond to the one you use the most.

The [includeif] section tells Git to use a different .gitconfig file for anything that happens in ~/GitHub/waldo/. This nested .gitconfig file has precedence over the global one, and looks like this:

# /Users/You/GitHub/waldo/.gitconfig

[user]
  name = waldo
  email = waldo@example.com

[url "git@waldo-github.com"]    # This is the alias we defined in ~/.ssh/config
  insteadOf = git@github.com

Here, we override the default user with waldo.

The [url] section tells Git to replace the default remote URL with the alias we defined in ~/.ssh/config.

6. Test it out

The default github.com host should return the default account, foobar:

$ ssh -T git@github.com
Hi foobar! You've successfully authenticated, but GitHub does not provide shell access.

Whereas the waldo-github.com host should return the second account, waldo:

$ ssh -T git@waldo-github.com
Hi waldo! You've successfully authenticated, but GitHub does not provide shell access.

Navigate to any project in ~/GitHub/ (except ~/GitHub/waldo/) and run:

$ git remote -v
origin  git@github.com:foobar/project-toto.git (fetch)
origin	git@github.com:foobar/project-toto.git (push)

Now go to ~/GitHub/waldo/project-tata:

$ git remote -v
origin	git@waldo-github.com:waldo/project-tata.git (fetch)
origin	git@waldo-github.com:waldo/project-tata.git (push)

See how the host is automatically replaced with the alias we defined in ~/.ssh/config.

The same applies to git clone:

$ git clone git@github.com:waldo/project-gaga.git
Cloning into 'project-gaga'...
...
$ cd project-gaga
$ git remote -v
origin	git@waldo-github.com:waldo/project-gaga.git (fetch)
origin	git@waldo-github.com:waldo/project-gaga.git (push)

That means you're all set!

Sources

Changelog

date comment
2024-01-07 add a changelog
2023-08-25 add a section to persist SSH keys upon reboot, add a thorough example with .gitconfig file, wording
2023-08-24 initial release
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment