Managing git config by folder with includeIf
I have accounts to different Git forges: GitHub, GitLab, where I have a personal and professional accounts, as well as Codeberg, and hopefully one day, my self-hosted Forgejo. I keep all of my local repositories neatly organized in subfolders like this:
.
├── dev
│ ├── gitlab
│ │ ├── Richard-Degenne
│ │ │ └── repo-1
│ │ └── Perfect-Memory
│ │ └── repo-2
│ └── github
│ └── repo-3
│ └── github
│ └── repo-3
This is pretty neat, but it poses one very specific challenge. My accounts do not use the same e-mail addresses. For example, my professional GitLab account uses my work e-mail address. And even for my personal accounts, I use either sub-addressing or my own e-mail server.
Because of this, configuring the e-mail address I use for commits becomes a bit of a hassle. I can't use git config --global user.email because that would mean that all repositories would use the same e-mail address, which is not what I need.
The hard way would be to not have a global e-mail address, and use git config --local user.email in each of my repositories, but that would be ungodlily (yep, that's a word!) tedious.
Surely there's an elegant way to go about it? So I went digging in the documentation for git config...
A hidden gem?
Introducing... Conditional includes. In its infinite wisdom, Git has a way to include a separate .gitconfig file if and only if certain conditions are met. Among the available operators are gitdir, which checks whether the current repository's .git path matches a certain pattern. Isn't that fabulous?
So here's the plan: create multiple .gitconfig files that describe my various identities, and, in the global ~/.gitconfig, use includeIf directives to include them based on the path of the repository. Sounds simple enough? Here we go.
Let's start by creating these unitary .gitconfig files:
; dev/gitlab/Richard-Degenne/.gitconfig
[user]
email = <my personal GitLab e-mail address>
; dev/gitlab/Perfect-Memory/.gitconfig
[user]
email = <my work e-mail address>
; And so on and so forth for my different identities...
And, in my main ~/.gitconfig file:
[includeIf "gitdir:~/dev/gitlab/Richard-Degenne/"]
path = ~/dev/gitlab/Richard-Degenne/.gitconfig
[includeIf "gitdir:~/dev/gitlab/Perfect-Memory/"]
path = ~/dev/gitlab/Perfect-Memory/.gitconfig
; ...
Alternatively, you can also set these sections from the command line:
git config --global includeIf.gitdir:~/dev/gitlab/Richard-Degenne/.path ~/dev/gitlab/Richard-Degenne/.gitconfig
And there we go! You can test your setup by going into a repository and querying git config --local user.email and seeing that it returns the right address. How cool is that!
It's even better with SSH!
Obviously, there are probably a ton of other neat use-cases for this feature.
For example, since I try to have good security hygiene, I use separate SSH keys for my different accounts, and I use the same conditional include feature to customize which key to use on a per-folder basis with the <a href="https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresshCommand">core.sshCommand</a> setting:
; dev/gitlab/Richard-Degenne/.gitconfig
[core]
sshCommand = ssh -i ~/.ssh/id_personal
; dev/gitlab/Perfect-Memory/.gitconfig
[core]
sshCommand = ssh -i ~/.ssh/id_professional
Conclusion
Definitely an article on the shorter side of things, but I've been struggling to write often, so I though why not share this little tidbit! Anyway, very neat feature, 10/10 would recommend. Also, take a look at the other available operators. I don't think I have a use for them, but you might!