Managing multiple Git configurations
Tags: git, github
Published: 2020-11-25 15:20:31

Using the same computer for both work-related and personal projects may cause you to write Git commit messages with your private email on your work projects or vice-versa. That is assuming that you configured Git with the --global flag, which applies the configs to every repo on your OS user account.

But, what if there was an easy way to separate your Git configs, whether you're dealing with private or work repositories, accordingly? I have great news for you: if you're using Git with, at least, version `2.13`, you can have [Conditional Includes](https://git-scm.com/docs/git-config/#_conditional_includes).

You might be wondering:

> That's great. But how does it help me?

Worry no more!

The "middle" Git config level is the global one, which means that your configurations are stored on a `~/.gitconfig` file. 

Wondering how that file looks? Here's mine:

```shell
~
▶ cat .gitconfig
[user]
 signingkey = C9KF0E358V41E9C5
 name = Rafael Almeida
 email = rafaelcpalmeida@----.com
[gpg]
 program = gpg
[commit]
 gpgsign = true
```

Now, let's assume that I wanted to use:

> The email rafaelcpalmeida@----.com with the GPG key C9KF0E358V41E9C5 on my private repositories.

and

> The email rafael.almeida@company.com with the GPG key 9VKF4E35KV4LE935 on my work repositories.

That could be easily achieved by creating two new files: one with the configurations for your personal repositories and one for the work-related ones. Here are mines:

```shell
~
▶ cat .gitconfig_personal
[user]
 signingkey = C9KF0E358V41E9C5
 name = Rafael Almeida
 email = rafaelcpalmeida@----.com
~
▶ cat .gitconfig_company
[user]
 signingkey = 9VKF4E35KV4LE935
 name = Rafael Almeida
 email = rafael.almeida@company.com
```

Now, all I have to do is to reference them on my original `.gitconfig` file. Again, here's mine, now updated:

```shell
~
▶ cat .gitconfig
[gpg]
 program = gpg
[commit]
 gpgsign = true
[includeIf "gitdir:~/company/"]
 path = .gitconfig_company
[includeIf "gitdir:~/projects/"]
 path = .gitconfig_personal
```

The file above uses the configuration of each of the files but only if the path where the repository I'm interacting with matches the path specified on the configuration file.

Here's a demo:

```shell
~/company
▶ mkdir test && cd test
~/company/test
▶ git init
Initialized empty Git repository in /Users/rafaelalmeida/company/test/.git/
~/company/test master
▶ touch a
~/company/test master
▶ git add .
~/company/test master
▶ git commit -m "Testing git configs"
[master (root-commit) 6d5b06e] Testing git configs
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a
```

Looking at my `git log`, the output I get is:

```shell
commit 6d5b06ef2678b921436b1c17a1d5684302c9a722 (HEAD -> master)
Author: Rafael Almeida <rafael.almeida@company.com>
Date: Tue Nov 24 00:30:21 2020 +0000
Testing git configs
```

Wondering what happens if I do the same on `~/projects`? Here:

```shell
~/projects
▶ mkdir test && cd test
~/projects/test
▶ git init
Initialized empty Git repository in /Users/rafaelalmeida/projects/test/.git/
~/projects/test master
▶ touch a
~/projects/test master
▶ git add .
~/projects/test master
▶ git commit -m "Testing git configs"
[master (root-commit) 2ee78dc] Testing git configs
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a
```

And here's my `git log`:

```shell
commit 2ee78dcd2d154ff227982ad2e04644dd98f64c6c (HEAD -> master)
Author: Rafael Almeida <rafaelcpalmeida@----.com>
Date: Tue Nov 24 00:33:30 2020 +0000
Testing git configs
```

---

And this is how you can manage different Git configurations without any fuzz. Want to share your feedback? Let me hear you in the comments below!