As an independent software engineer I often find myself working with clients who use different Git providers or who might require me to have a client-specific Git configuration. For a long time this resulted in me having a complex and difficult to maintain Git configuration, and some really hacky shell aliases which did some on the fly Git reconfiguration depending on which repository I was in… Not nice!
But then I discovered what seems to be a little known piece of Git configuration. which goes by the name of
This configuration, which exists in Git vertion 2.36 onwards, allows Git to conditionally include configuration based on a pattern match, which is applied to the remote URL of each repository. The pattern matching is flexible enough that it can be used to identify different Git providers e.g. Gitlab vs GitHub or different path segments (which often map to repositories owned by a particular client).
Let’s start with a user story (albeit a slightly contrived one where I’m the user!):
As a software engineer working with multiple clients who use Git When I work with a Git repository belonging to a given client I want Git to automatically configure itself with the correct settings for that client So that I can keep my Git configuration simple And so that I can maintain separate Git configuration for each client
Here’s a worked example:
Let’s say I’m working with 2 clients right now:
- Funky Corp
- Groovy Corp
Both of the above clients have their own GitHub organisation, where they keep their source code:
- Funky Corp:
- Groovy Corp:
Each organisation requires me to:
- Use a GitHub account which is specific to their organisation.
- Using an email address which is specific to their organisation.
- Use a GPG signing key which is specific to their organisation.
Using the new syntax I can configure my
.gitconfig file to conditionally include the relevant config for each of the 2 clients mentioned above:
# Start with defaults. [core] autocrlf = input [init] defaultBranch = main # Here are the conditional, organsation specific includes. [includeIf "hasconfig:remote.*.url:firstname.lastname@example.org:funkycorp/**"] path = "~/.gitconfig.funkycorp.inc" [includeIf "hasconfig:remote.*.url:email@example.com:groovycorp/**"] path = "~/.gitconfig.groovycorp.inc"
I would then specify the appropriate settings for each client in the respective include file:
[user] email = firstname.lastname@example.org name = egfunk1 signingkey = <my funky corp gpg signing key> [commit] gpgsign = true
[user] email = email@example.com name = eggroove1 signingkey = <my groovy corp gpg signing key> [commit] gpgsign = true
Then, when I clone a repository from one client we can see that Git automatically applies the correct configuration:
gh repo clone funkycorp/test-repo git config --show-origin --show-scope --get user.name global file:/home/<username>/.gitconfig.funkycorp.inc egfunk1
All we’re doing here is matching the repository remote on its URL, so it should be perfectly possible to extend this out to other Git hosting providers e.g. BitBucket, GitLab etc.
Note: As per this note This feature is only available in Git 2.36 and later versions, earlier versions will silently ignore the additional configuration.
Let me know in the comments below if this helps you simplify your Git configuration.
Until next time!