When I clone a new project, I put the proper email address (e.g., a company email) as an author email in the local config stored in the repository. It worked fine until I started working for a client whose project is spread across many repositories that I cloned when needed.

I can’t count how many times I forgot to put the correct email into the local config of the newly cloned repository before committing anything into it – just because I was in a rush. In effect, my personal email (which occupies my global configuration) has been leaking many times into commits, sentenced to last forever in the git history. I’ve probably done it more times than I even realize.

To avoid making these mistakes, don’t use a global git configuration for identity.

Remove global configuration

To remove the global identity, use the following commands. If we use the same name everywhere, it makes sense to keep it set globally.

git config --global --unset user.email
git config --global --unset user.name

But this is not enough. Git will try to guess the name and email address based on the user profile and hostname. We need to instruct git to use only configuration files.

Use provided configuration only

Since version 2.8, git has a dedicated setting called user.useConfigOnly to control if it should guess the identity or use the configuration only. According to documentation:

Instruct Git to avoid trying to guess defaults for user.email and user.name, and instead retrieve the values only from the configuration. For example, if you have multiple email addresses and would like to use a different one for each repository, then with this configuration option set to true in the global config along with a name, git will prompt you to set up an email before making new commits in a newly cloned repository. Defaults to false.

The funny thing is that even documentation points out this as a potential solution to my problem.

To change this option, we can use the following command

git config --global user.useConfigOnly true

Now, if we try to commit anything to the repository that has no configured author’s name and email, git shows us the message about missing configuration.

Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "[email protected]"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: no email was given and auto-detection is disabled

Now it’s hard to commit anything under a mistaken identity, but we need to configure each repository individually. To make it easier, we can prepare a few small scripts.

Prepare scripts to set up identity

The idea is simple. Whenever we get the message about the unknown identity, we can invoke a simple bash script to configure the proper profile.

#!/bin/bash

git config --local user.name "Szymon Krajewski"
git config --local user.email "[email protected]"

echo "Szymon Krajewski <[email protected]> applied as git user to this repository."

Let’s call it apply_personal_profile and make it executable.

chmod +x apply_personal_profile

You can create as many profiles as you need. I prepared a personal profile, a company profile, and one related to the client I currently work for.

I store my profiles in the dedicated directory ~/Utilities/git/profiles. I added this directory to $PATH global variable in my .zshrc, to make these scripts available from everywhere. Alternatively, you can symlink each script into /usr/local/bin, and that’s also OK.

# .zshrc
export PATH="$PATH:/Users/szymon/Utilities/git/profiles"

Apply author profile to repository

Whenever you clone or init a new repository, run one of the created scripts. If you forget about this, don’t worry – git won’t let you commit without configured email.

apply_peronal_profile

Other approaches

The simpler one

The script isn’t complicated, but it’s also not perfect. I’m sure it could be better – no duplications, basic checks, and so on – but I wanted to start small. Surprisingly, this is a single line that matters

git config --local user.email "[email protected]"

You can make an alias in your shell or search in command history for that one. The name is usually the same across profiles and can be configured globally.

Automatic

There are also tools that can do automatic profile switching based on the directory name, location, or existence of a particular file, e.g. gitconfig’s conditional includes or direnv, but I haven’t tested them. I took the most straightforward approach – improvements may come with time if needed.