Path-Aware Git Config

Introduction

Most companies would ask employees to use their company email addresses in internal Git repositories. But many of us are not comfortable with using the company email in personal contributions to open source projects. Meanwhile, for people who have become a committer in several open source organizations and were assigned email addresses specific to them, if they prefer attributing contributions to the corresponding organization email addresses, they have to set separate git config in each repository, or else the email used will be the global default.

However, Git 2.13 introduced conditional configuration includes. Combined with the gitdir: keyword, it’s possible to import Git configuration from different files for repositories under different paths.

Configuration

First, upgrade your Git if it’s below version 2.13! Next, create a new file with organization-specific settings like user.email. Last, add the [includeIf] sections to your ~/.gitconfig. Remember to try it out by cloning a new repository under the gitdir path and make a new commit!

$ tail -n5 ~/.gitconfig
[user]
  name = Zero King
  email = l2dy@example.com
[includeIf "gitdir:~/Repos/work/"]
  path = .gitconfig-work
$ cat ~/.gitconfig-work
[user]
  email = hidden@work.o

Nerd Facts

Man pages FTW!

  • Actually I have added ** at the end of each gitdir condition in my config, but there’s no difference if the pattern ends with /.
  • Included files are searched relative to the including file, so an absolute path like ~/ before the path is not required if they are in the same directory.
   Conditional includes
       You can include a config file from another conditionally by setting a
       includeIf.<condition>.path variable to the name of the file to be
       included.

       The condition starts with a keyword followed by a colon and some data
       whose format and meaning depends on the keyword. Supported keywords
       are:

       gitdir
	   The data that follows the keyword gitdir: is used as a glob
	   pattern. If the location of the .git directory matches the pattern,
	   the include condition is met.

...

	   o   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.

...

   Example
	   ; relative paths are always relative to the including
	   ; file (if the condition is true); their location is not
	   ; affected by the condition
	   [includeIf "gitdir:/path/to/group/"]
		   path = foo.inc