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
Instruct Git to avoid trying to guess defaults for
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
truein 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
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 "firstname.lastname@example.org" 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@example.com" echo "Szymon Krajewski <firstname.lastname@example.org> 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.
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@example.com"
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.
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.