Many of us have at least two Git accounts: a company one used for day-to-day work, and a private one with all our beloved pet projects. There is often a company policy forbidding using private accounts and emails in commits (e.g. due to external regulations to which the company is subject). Also, we often have different SSH keys for our git accounts. On the other hand, we don’t want to use a company identity in our after-hours activities. Would be nice to use different configs depending on a repository.

Things to customize

There are few settings that we want to change depending on type of the repository. For sure, we would like to change the email, maybe name to nick, and of course an SSH private key. Name and email are easy to set within the following entries in ~/.gitconfig:

[user]
  name = My Name
  email = myemail@example.org

The SSH key is a bit trickier since we have no option for that in git, at least not the obvious one. Fortunately, starting from Git 2.10, we can customize the SSH command used by the git, thus we can override the default key:

[core]
  sshCommand = ssh -i ~/.ssh/my_custom_id_ed25519

We know what to change but there’s one more question. How can we do it?

Repository specific settings

Git stores its global config in ~/.gitconfig but also looks for repository specific details in <local-repo>/.git/config. So in order to change our identity we need to modify this file within a text editor or by using git config commands. The main drawback of this approach is that you always need to remember to modify settings for each cloned repository and trust me, sooner or later you’ll forget about it and create commits with the wrong email. If you’re lucky you’ll notice this before the push and you’ll be able to rewrite commits with proper metadata.

Yeah, it works, but it’s very manual thus error-prone approach. I would like to just clone a repository and start working.

Can we come up with something better?

Directory specific settings

Many fellow developers, including me, separate work projects from private ones using different parent directories. It turns out that git supports conditional config directive depending on the directory we are in. Sounds promising, let’s try it. First, we need to create custom configs, let say ~/.gitconfg-work:

[user]
  name = My work name
  email = my-work-email@example.org
...
[core]
  sshCommand = ssh -i ~/.ssh/my_work_id_ed25519

and ~/.gitconfig-private (or ~/.gitconfig-saving-the-world if you like):

 [user]
   name = My private name
   email = my-private-email@example.org
 ...
 [core]
   sshCommand = ssh -i ~/.ssh/my_private_id_ed25519

Then we need to augment the main ~/.gitconfig file with two directives:

[includeIf "gitdir:~/projects/work/"]
	path = ~/.gitconfig-work

[includeIf "gitdir:~/projects/private/"]
	path = ~/.gitconfig-private

Pay the attention to / at the end of the gitdir pattern. It works as the ** wildcard enabling conditional configs for all subdirectory of the given path. See the docs for more details.

Keep in mind that includeIf should be placed at then end of ~/.gitconfig otherwise your custom config could be overwritten by the values placed below the directives. More here.

Right after that you can go to your work or private directory and clone a new repository using a valid config. You can also continue the work with already existing repositories. New configs should apply to them as well (unless you’ve overridden something locally in the repository).

Conclusion

From now on you don’t have to remember and worry about switching between identities, simply stick with separating directory structure which in my opinion is quite natural.

References: