When you are working with multiple Git accounts across different git-providers it’s hard to manage access to all these repositories. When you search for a solution you will find different ways to solve this problem.
Basically it comes down to two SSH-based solutions;
- Use named SSH configurations in the
~/.ssh/configfile. - Use the git
includeIfdirective.
Both methods will be explained in detail but before we dive into each method I first want to set a baseline on the SSH-keys.

SSH-keys
Each method relies on the SSH-keys being uploaded to your git-provider (.pub only please!). The upload process is different for each provider.
The SSH-keys are stored by default in the directory ~/.ssh/.
The naming convention used for the SSH-keys is [git-user.name]@[git-provider].ed25519.
- git-user.name, the user name at your git provider.
- git-provider, the name of the git provider, including domain to separate possible internal and external git providers.
- ed25519, instead of the default RSA key I use Ed255191
The command to create the SSH-key pair:
syntax
ssh-keygen -t ed25519 -f ~/.ssh/[git-user.name]@[git-provider].ed25519 -C "[git-user.name]@[computer-name]"
example
ssh-keygen -t ed25519 -f ~/.ssh/tisgoed@github.com.ed25519 -C "tisgoed@MacFlurry"
As best practice add a comment ('-C' argument) with your git-user.name and the computer-name. It helps to identify the SSH-keys at your git-provider.
I re-use my SSH-keys for a specific git account per computer but not shared across computers. If for some reason your workstation is no longer available, you can identify and disable the SSH-keys at your git-provider.
Method 1: Use named SSH configurations
In this method a “named” entry is created in the .ssh/config file. The entry content refers to the git-provider specific SSH-keys. The name of the entry is used in the git configuration’s remote origin.
This method gives you full flexibility on the location of your local repositories.
Diagram for the named SSH configuration flow
The following diagram describes the configuration for a new git account:
The basic steps to set up a new git-provider:
- Create SSH-keys
- Add the named SSH-section
- Set the remote origin
The baseline for setting the SSH-keys is already described in the second paragraph. Moving on to step 2.
Step 2: Add a named SSH-section
For this step you need to modify the SSH-configuration file (~/.ssh/config).
See the template and example of the named section below on what to add for your new git-provider.
A template of a named (git account) section in the ~/.ssh/config file:
...
# GitProvider description [your git-user.name] account
Host [git-user.name]-[git-provider]
HostName [git-provider]
user git
IdentityFile ~/.ssh/[git-user.name]@[git-provider].ed25519
IdentitiesOnly yes
...
An example of two fictional named sections in the ~/.ssh/config file:
...
# tisgoed @ GitHub.com
Host tisgoed-github.com
HostName github.com
user git
IdentityFile ~/.ssh/tisgoed@github.com.ed25519
IdentitiesOnly yes
# tisgoed @ BitBucket.com
Host tisgoed-bitbucket.com
HostName bitbucket.com
user git
IdentityFile ~/.ssh/tisgoed@bitbucket.com.ed25519
IdentitiesOnly yes
...
The SSH-Host identifies the account to be used to login to the git-provider.
For each git account you will need to add a different section in your ~/.ssh/config file.
Step 3: Set the remote origin
When you clone a new repository you end up with the default remote origin in your .git/config configuration.
A partial example of the default `[remote “origin”] in your fresh git-configuration:
...
[remote "origin"]
url = git@github.com:tisgoed/my-new-repo.git
fetch = +refs/heads/*:refs/remotes/origin/*
...
As you can see the url points to your repository but the way it wants to connect does not use the named configuration.
We need to modify the default remote origin to use our named SSH configuration.
See the syntax and the example below on how to modify the remote origin through the command line.
The syntax:
git clone git@github.com:[git-user.name]/[repo-name].git
cd [repo-name]
git remote add origin git@[git-user.name]-[git-provider]:[git-user.name]/[repo-name].git
An example:
git clone git@github.com:tisgoed/silly-repo-name.git
cd silly-repo-name
git remote add origin git@tisgoed-github.com:tisgoed/silly-repo-name.git
The url in the [remote "origin"] of the git-configuration should be changed similar to the example below:
...
[remote "origin"]
url = git@tisgoed-github.com:tisgoed/silly-repo-name.git
fetch = +refs/heads/*:refs/remotes/origin/*
...
Altough this is a good solution, and it gives you full flexibility on the working directory, the alternative option simplifies it even further without touching the ~/.ssh/config file and setting the specific remote origin for each repository.
New repo workflow (method 1)
When you need to create a new repo at an existing git-provider, the following steps apply:
- Browse to your (git-provider)
- Login to your account (git-user.name)
- Create a new repository (repo-name
git clone git@[git-provider]:[git-user.name]/[repo-name].gitcd [repo-name]git remote add origin git@[git-user.name]-[git-provider]:[git-user.name]/[repo-name].gittouch README.mdgit add .git commit -m "Initial commit"git push -u origin master
Step 4 and 6 could be combined in this workflow. I have tried this workflow for a while and noticed that I needed all ten steps simply because I could not remember the named of the SSH-section.
git clone git@tisgoed-github.com:tisgoed/silly-repo-name.git
Method 2: Use the git includeIf directive
The includeIf-method uses the git directive includeIf that enables you to include files when a certain condition is true.
If you use git within a certain path, the content of a specific file is added to the active git-configuration. The included file contains information to access a specific git-provider.
This method requires more steps to set up but there is no need to remember a named SSH-section.
Diagram with the includeIf flow
The following diagram describes the configuration for a new git account:
The basic steps to set it up for a new git-provider:
- Create SSH-keys
- Set up a directory structure
- Create the include file(s)
- Add the “includeIf” to the git configuration
- Verify the loading of the conditional git config (optional)
The baseline for setting the SSH-keys is already described in the second paragraph. Moving on to step 2.
Step 2: Git directory structure
Different directory structures are possible. I tried various structures like:
- “~/git/[git-provider]/[git-user.name]” and
- “~/[git-provider]/[git-user.name]”
- “~/git/[git-user.name]@[git-provider]/”
My current preferred directory structure is “~/git/[git-user.name]@[git-provider]/”.
An example of my git “root” directories:
...
git
├── tisgoed@bitbucket.com
├── tisgoed@gitlab.com
└── tisgoed@github.com
...
The further description of the includeIf-method is based on this directory structure.
Step 3: The git-include file(s)
In my user-root (~) directory next to the .gitignore and the .gitconfig I created a directory named .gitinclude to store the include files.
...
.gitconfig
.gitignore
.gitinclude
├── tisgoed@bitbucket.com.include
├── tisgoed@gitlab.com.include
└── tisgoed@github.com.include
...
The following naming convention is used for the include files:
[git-user.name]@[git-provider].include
The content of an include file requires at least the following two sections:
user-section, user dataname, the user name at the git-provider.email, the email address at the git-provider.
core-section,sshCommand, the reference to the provider specific SSH-key
An include template:
[user]
name = [git-user.name]
email = [git-user.email]
[core]
sshCommand = "ssh -i ~/.ssh/[user-name]@[git-provider].ed25519"
An include example, ~/.gitinclude/tisgoed@github.com.include
[user]
name = tisgoed
email = a.w.alberts@tisgoed.nl
[core]
sshCommand = "ssh -i ~/.ssh/tisgoed@github.com.ed25519"
Step 4: The ~/.gitconfig file
Once an include file is created we can add the includeIf section to the ~/.gitconfig file.
At first the syntax for the includeIf directive is a bit confusing. Basically it comes down to the following pseudocode:
if (git-repository is placed within path) then
add configuration from file
end if
The template for the includeIf section in the ~/.gitconfig file:
...
# Git includes
# git-user.name @ git-provider
[includeIf "gitdir/i:~/git/[git-user.name]@[git-provider]/"]
path = ~/.gitinclude/[git-user.name]@[git.provider].include
...
An example with three different git accounts in the ~/.gitconfig file.
...
# Git includes
# tisgoed @ bitbucket.com
[includeIf "gitdir/i:~/git/tisgoed@bitbucket.com/"]
path = ~/.gitinclude/tisgoed@bitbucket.com.include
# tisgoed @ github.com
[includeIf "gitdir/i:~/git/tisgoed@github.com/"]
path = ~/.gitinclude/tisgoed@github.com.include
# tisgoed @ gitlab.com
[includeIf "gitdir/i:~/git/tisgoed@gitlab.com/"]
path = ~/.gitinclude/tisgoed@gitlab.com.include
...
Step 5: Verify the git configuration
While setting things up you can use the git config --list command to check if the include file was loaded into the git configuration. It should display the user.name and the user.email from the include file.
⚠️ The following command only works in a ‘git’ directory.
The command:
git config --list | grep "user."
A sample of the expected output
user.name=tisgoed
user.email=a.w.alberts@tisgoed.nl
New repo workflow (method 2)
When you need to create a new repo at an existing git-provider, the following steps apply:
- Browse to your (git-provider)
- Login to your account (git-user.name)
- Create a new repository (repo-name)
cd ~/git/[git-provider]git clone git@[git-provider]:[git-user.name]/[repo-name].gitcd [repo-name]touch README.mdgit add .git commit -m "Initial commit"git push -u origin master
Conclusion
Pro’s and con’s of both solutions:
- Use named SSH configurations in the
~/.ssh/configfile.- Full flexibility on the location of your repositories.
- Requires setting git-account per git-provider in
~/.ssh/config. - Requires setting the remote origin SSH-setting in the repository.
- Requires you to remember the name of the SSH-section.
- Using the git
includeIfdirective.- Static “root”-directory per git-account.
- Create
git-includefile per git-account. - Requires changing your
~/.gitconfigfile per git-account.
I tried both methods and personally I prefer the second option. It forces you to keep a clear separation between the different git-accounts, there is no need to change the default remote origin and there is no need to remember the name of the SSH-section.
References
- How to Deal with Multiple GitHub Accounts on One Computer
- Setting up multiple GitHub accounts, the nicer way
Git conditional includes:
Git tooling:
- Create new github repo from command line
- GitHub/hub, A command-line tool that makes git easier to use with GitHub.
- hub: use github from the command-line
ED25519:
-
ED25519 is an elliptic curve cryptography(ECC) signature algorithm. The Ed25519 signature alghorithm offers high security signatures with a small signature size. ↩︎