Configuring Git for Work How to use your work email in your work repositories

November 17, 2020

You can override your globally configured email inside individual repositories, allowing you to use your work email for work-related repos. Setting this up for each repo—and remembering to do so—is cumbersome. Luckily, there is an easier way to accomplish this for all repos within a certain directory.

One of the first things you did when you set up Git was to configure your name and email:

$ git config --global user.name "Jane Doe"
$ git config --global user.email jane@mail.com

The above commands added the following lines to your global Git configuration file ~/.gitconfig:

[user]
	name = Jane Doe
	email = jane@mail.com

Each repository also has its own Git configuration located at .git/config. Configs in the local file take precedence over the global configs.

You can set configs in .git/config manually or by passing the --local flag to git config. Thus, if I want to use my work email in a specific repo, I need to set it as follows:

$ git config --local user.email doe@acme.org

If you want to do this for all work repos, it gets a bit cumbersome. Above all, it’s easy to forget to do this for repos that you’ll clone or create in the future.

Fortunately, Git has a more scalable approach to this problem. You can conditionally include further Git config files based on the directory of a Git repo.

Let’s assume that all my work-related repos are inside the folder ~/Documents/Acme/repos/.

First, I’ll create a separate Git config file ~/.gitconfig-work that contains my work-related overrides:

[user]
	email = doe@acme.org

Then, I include this file from my global Git config file in ~/.gitconfig:

[includeIf "gitdir:~/Documents/Acme/repos"]
	path = .gitconfig-work

It’s important to place above snippet at the end of your ~/.gitconfig file because, according to the documentation on git-config:

The contents of the included file are inserted immediately, as if they had been found at the location of the include directive.

If we were to restructure our work directory, e.g. by changing Acme to acme or by moving the repositories somewhere else, such as to ~/repos/acme/, the include directive would no longer apply. My newly created commits would now use my globally defined private email rather than my work email. Most likely, I wouldn’t even notice.

To prevent this from happening, we can generalize the path used in the include directive above. First, we can use gitdir/i to perform the matching case-insensitively. Further, there are a few assumptions around the path that can help us. From the docs:

  • If the pattern does not start with either ~/, ./ or /, **/ will be automatically prepended. For example, the pattern foo/bar becomes **/foo/bar and would match /any/path/to/foo/bar.

  • If the pattern ends with /, ** will be automatically added. For example, the pattern foo/ becomes foo/**. In other words, it matches “foo” and everything inside, recursively.

Equipped with this knowledge, we can generalize the include directive so that it applies to any Git repository that is nested within a folder named after my company—case-insensitively, mind you:

[includeIf "gitdir/i:acme/"]
	path = .gitconfig-work

To verify that this is working, I can look up the resolved config value in a specific repo:

$ cd ~/repos/private/my-project
$ git config user.email
jane@mail.com

$ cd ~/Documents/Acme/repos/website
$ git config user.email
doe@acme.org

I encourage you to check out the git-config manual (git help config). You’ll find some interesting things in there. For instance, an include directive can be conditional on the branch you’re currently on.