weather: getting warmer
mood:    B+

3 minute read
---

# Using Multiple Git Identities

As I am slowly transitioning from using github as my main hosted git platform,
to sourcehut[1] and codeberg[2], I am running into the issue that I want to use
a different git identity per provider. For example, I still use github at work,
so this means I need to be able to push commits under my real name, and with a
different email address. But on sourcehut and codeberg, I want to use a
different email and an alias for my name. This presented me with a practical
problem: is there an easy way to switch my gitconfig, based on the service I
use?

Of course, I could keep it simple and stick with a global ~/.gitconfig, while
modifying a local, per-repostory ~/.git/config in order to update my identity
as needed. However, this is not only error-prone (it's very easy to commit a
change with the wrong identity if I forget to change it), but it is also very
inefficient to do this for the 100+ repositories I have, especially considering
a situation where I want to change my details for many repositories at once.


## Git identity per service

So I was looking for another approach. Luckily, a solution exists in the form
of the includeIf directive, combined with "hasconfig:remote.*.url:" - something
that has only been introduced since git version 2.36 (early 2022). In short, it
allows me to specify a unique config for every platform like this:

~/.gitconfig:

[includeIf "hasconfig:remote.*.url:[email protected]:*/**"]
   path = ~/.gitconfig-github

[includeIf "hasconfig:remote.*.url:[email protected]:*/**"]
   path = ~/.gitconfig-sourcehut

[includeIf "hasconfig:remote.*.url:[email protected]:*/**"]
   path = ~/.gitconfig-codeberg


As an example, this is the contents of ~/.gitconfig-github:

[user]
   name = JohnDoe
   email = [email protected]


Of course, you can add any valid git config in here as long as you keep in mind
that if the git repository you're in doesn't have a remote (yet), you might not
have a [user] identity set.

This can be circumvented by configuring a [user] identity in your main
gitconfig and then having these includeIf statements overwrite it.


## Git identity for personal and work

The neat thing about includeIf is that it also works in a number of other
situations. Imagine if you have one directory where you keep all of your
personal code and one where you keep all your work projects, you could then do
something like this (assuming those directories exist):

[includeIf "gitdir:~/code/personal/"]
   path = .gitconfig-personal

[includeIf "gitdir:~/code/work/"]
   path = .gitconfig-work


Every git repository that is created or cloned in these directories will now
automatically assume the correct identities.


## Git identity per branch

As a final example, consider a situation where you need a different identity,
depending on the branch you're on. Again, this is perfectly possible to do with
includeIf:

[includeIf "onbranch:release"]
   path = .gitconfig-release


---

Even though all of this is well documented (git config --help | grep
includeIf), I don't come across a lot of people who actually have things set
up like this. It was easy to do and pretty useful if you need to work on
projects across different git hosting platforms. In any case, I've found this
useful to know.


---
[1] https://sr.ht
[2] https://codeberg.org