Git Conditional Includes

June 6, 2017

One of the features that slipped quietly into Git 2.13 is the notion of "conditional includes" for configuration files, and it's one of my favorite new features. Although it's really simple, it's also extremely important for people who work both on Enterprise software and open source projects.

When I work on my open source projects, I end up pushing them to GitHub - and I have to authenticate when I do, so GitHub knows that I'm ethomson@edwardthomson.com. And when I'm working at my day job, I push my repositories to Visual Studio Team Services - and I have to authenticate there, too. So VSTS knows that I'm ethomson@microsoft.com.

But since Git is a distributed version control system, there's no authentication when I'm working in my local repository. When I commit, my changes go into the repository on my computer. That means that I need to tell Git who I am - my name and my email address - and Git will dutifully record that information the commits as I create them.

The problem here is that now I'm on my own to manage the settings for my name and email address - and I want to make sure that I keep my day job separate from the work I do in open source. I don't want to use my work email address on my open source projects because I don't want anybody to run git log and think that it's a project that's sponsored by my employer. And if I ever change jobs, the email address in the repository's history will stop working.

More importantly, I don't want to use my personal email address in our corporate Git history. People tend to get a little jumpy when they see that somebody has checked in code and their email address doesn't end in microsoft.com. And although my personal address is pretty boring, I imagine this is especially important for people who's email addresses are a bit more "creative". Otherwise, you may show up at work on monday morning with a clever new nickname. (I'm talking to you, reeferman42@example.com.)

So I try to make sure to keep my professional work separate from my personal work.

Before Git 2.13 introduced conditional includes, I would have had to set up my corporate email address in my global Git configuration, and then remember to change it in any new repository where I want to use my personal email address. Unfortunately, it's really easy to forget to do this when all you want to do is clone a repository and quickly create a quick pull request. That means that it's easy to accidentally end up pushing a change with the wrong identity.

With conditional configuration includes, you have a lot more control over how your Git configuration is applied. You can set up some configuration to be applied based on the directory that you're in, so it's much easier to set up.

I keep all my libgit2-related repositories in one directory: C:\LibGit2. This is where libgit2, LibGit2Sharp, Rugged and the like live; all my other open source projects live in C:\Projects. Every other repository on my machine is work-related. So my global Git configuration (C:\Users\ethomson\.gitconfig on my Windows machine, or /Users/ethomson/.gitconfig on my Mac) looks like:

[user]
    name = Edward Thomson
    email = ethomson@microsoft.com
[includeIf "gitdir:C:/LibGit2/"]
    path = .gitconfig.oss
[includeIf "gitdir:C:/Projects/"]
    path = .gitconfig.oss

And I have a second file in my home directory, .gitconfig.oss that specifies only the configuration that I want to use when I'm hacking on open source projects, like libgit2:

[user]
    email = ethomson@edwardthomson.com

Note that the trailing slash is required, and on Windows, you need to specify your path using forward slashes - not backslashes. I make sure to keep these updated in my dotfiles repository, so that I won't forget them on a new machine.

Now when I'm working on a project that lives beneath C:\Projects, like my little hexdump utility that lives in C:\Projects\HexDump - or when I'm working on LibGit2Sharp, which lives in C:\LibGit2\LibGit2Sharp, then Git will set my identity as ethomson@edwardthomson.com.

For everything else - like the Visual Studio Team Services repository - it will use my work email address, ethomson@microsoft.com, ensuring that nobody at work gives me an embarassing nickname.

At least, if they do, it won't be because of my email address.