Avoid using global git identity
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
anduser.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 totrue
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 tofalse
.
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.