If you work with Git on multiple computers for multiple parties (yourself, company, another company) you’ve probably committed something with the wrong name/email already. Whenever I clone a company repository on my home computer, I have to go there and enter those notorious commands:
git config user.name "My Normal Name, not fancy nickname"
git config user.email "real.name@company.com"
You had to do this in each repository where your global config wasn’t satisfactory. And it was easy to forget. But then, in May 2017, Git 2.13 was released.
Conditional configuration
Git 2.13 brought Conditional includes where you could include another Git config if some condition was met. Available conditions are branch and git directory – and the latter is exactly what we want. Now to be honest, I’ve found other articles (1, 2) explaining the mechanism with pictures and file tree diagrams – yet I couldn’t make it work. There was nothing wrong with those, there was just something wrong with me.
This is not an attempt to make a better explanation and you can try any of those articles. Or find more – it’s double-easy when you know the name of the feature. I’ll reiterate the solution in short anyway. With a bit of anonymization (useless, I know, it’s all in the featured image), my ~/.gitconfig looks like this:
# normal .gitconfig content here
# and conditional includes at the end (can probably be anywhere)
# final / is crucial!
[includeIf "gitdir:C:/work/workspace/mycompany/"]
path = C:/work/workspace/mycompany/git-config.inc
Now we know a couple of things. I’m using Windows and at first I wasn’t sure how to write the paths. Can I use git-bash /c/work form? Now I can’t. Use normal Windows path, but with forward slashes.
But the slash!
The most important thing is the final slash. Directory mycompany is not a git directory – it’s just a directory under which I clone my company projects. The depth doesn’t matter. Now, if I adapted the examples from the aforementioned blog posts more cautiously I’d have no problem. But I forgot – or ignored – the final slash.
It is actually mentioned in the description of the feature in the docs – the fourth bullet says clearly:
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.
Instead, I got confused about how to write the path in Windows, later discovered that /** at the end helps (of course I needed the slash there) and only later tried to leave the trailing slash there. And after all this I found the description in the docs.
Now, this only underlines what I often say – but in this case disregarded – about reading manuals being worth it.
Notice also gitdir/i for case-insensitive pattern matching, but I didn’t need it here.
And the specific configuration
Finally, let’s get to the company specific Git configuration. But that is the easy part really. File path used in the config above is obvious – C:/work/workspace/mycompany/git-config.inc. Of course, it doesn’t have to be in the directory used in the pattern, but for me it’s more obvious this way.
Config has the same format like the main one and besides [user] section I also set autocrlf in [core] as the default autocrlf doesn’t suit us – at least not on Windows. But anything can go here:
[user]
name = My Normal Name, not fancy nickname
email = real.name@company.com
[core]
autocrlf = false
Testing
Testing it is easy – but you have to be in an actual Git repository, not just plain directory and not directly in the directory used in the path. If you remember this it’s easy to test this as the right configuration shows itself immediately when you call git config -l. The overrides will be displayed lower, so you will see also the original (global) config values. Alternatively you can check one key like git config user.name.
Try the same in some random tmp directory under that path – it will not work. Then git init that directory and it will work again. Great!
This is nice about Git – the right configuration works immediately, but it’s contextually sensitive. You have to be in the Git project and it must be under that path you specified. But then – that’s exactly what we wanted.
Good luck. Now we can keep forgetting to set newly cloned company projects.