The situation
Have you ever created a new Git repository for work on a personal machine or vice-versa, and accidentally made your first commit with the global Git email? Something like:
$ git config --global user.email
my@personal.email
$ git init
Initialized empty Git repository in /Users/yijiayu/work/project/.git/
$ echo "do stuff" > stuff.txt
$ git add .
$ git commit -m "Initial commit"
[master (root-commit) 340c447] Initial commit
1 file changed, 1 insertion(+)
create mode 100644 stuff.txt
$ git log -1
commit 4c497e117390eadc3bbc7e840d0dcce58bbcdc2b (HEAD -> master)
Author: Jiayu Yi <my@personal.email>
Date: Thu Feb 14 09:43:53 2019 +0800
Initial commit
Whoops!
The immediate fix for this would be to set your email at the repository level with git config user.email my@work.email"
and then amend the commit with git commit --amend --author="Jiayu Yi <my@work.email>" --no-edit
, but perhaps there is a more scalable way?
A solution
With conditional includes, you can
override your global configuration on a per-directory basis. For example, you could keep all your
work projects inside your ~/work
directory, and set your work email as the committer email for
projects under this directory. Let's see how to do this.
Creating a directory-specific Git configuration
We need to create a Git config file to apply for projects in ~/work
. The location of this file
doesn't actually matter, but putting it inside the root of the ~/work
directory makes sense.
We just want to override our email, so we'll create ~/work/.gitconfig
with the following content:
[user]
email = my@work.email
Setting up a conditional include for a directory
Next, we need to add some lines to the end of our global Git config file (usually located at
~/.gitconfig
) to tell Git to refer to our work-specific Git config when when we're under ~/work
:
[includeIf "gitdir:~/work/"]
path = ~/work/.gitconfig
This tells Git to load the Git config file at ~/work/.gitconfig
if the .git
directory for the
repository you are currently working on is located under ~/work/
. When this happens, the settings
it contains will override the global Git configuration defined higher up in the file—in this case
the user.email
key defined in ~/work/.gitconfig
will override the one in ~/.gitconfig
.
That's it! Now when you create a new repository inside the ~/work
directory, the committer email
for the repository will default to your work email instead of your personal one, without needing to
manually set it.
Additional notes
The path passed to the includeIf
directive is used a glob pattern, so it can
contain wildcard characters.
It also supports a the gitdir/i
keyword instead of gitdir
, which will match the provided pattern
case-insensitively.
Refer to the git-config
documentation
for more details.
Conclusion
Following up from my previous post on organising local Git repositories based on remote URL, conditional Git includes can be combined with a logical directory structure to automatically share relevant settings between related repositories, simplifying the cognitive load of switching between multiple projects.