This gist exists to display how I manage my Git configuration for different identities (e.g. personal and work identities) using the default configuration chain in Git.
My global git configuration is stored in my dotiles repository, which is public, but includes no work-related git configuration. Instead, that lives in and is managed by other files on my system, which are not synced to that public dotfiles repository. With just a few small configuration changes, you can learn how to do this too.
This process relies on the includeIf
conditional include statement within
Git's configuration file, and a little on-disk organization is necessary in
order to avoid introducing a heavy maintenance burden (e.g. needing to add new
configuration for each repo you clone).
There's just one rule:
- Per identity, have a common parent folder in which you clone all of the relevant repositories
As an example, I have a folder called code
in my user's home directory (~
).
Within this folder lives every repository I have or will ever clone, namespaced
by the repository URI. For example, a repository located at github.com/foo/bar
is cloned to ~/code/github.com/foo/bar
.
When cloning a new repo, you can do this in one shot (git
will create folders
that don't exist):
git clone [email protected]:foo/bar.git ~/code/github.com/foo/bar
Note
You can follow this same pattern of organizing your repositories, if you wish,
or come up with your own system that aggregates all identity-related
repositories into a parent folder unique to them. It could be as simple as
~/code/work
and ~/code/personal
!
The first part of this process is to include a local configuration file at the
bottom of my global git configuration file. This file doesn't need to exist! If
it doesn't exist, Git will quietly ignore it (you won't get errors while running
git
commands).
Place this at the very bottom of your git configuration:
[include]
path = ~/.config/git/config.local
Tip
You can name this file whatever you want -- just be sure to provide the right filename.
You can skip this step if you do not plan on sharing your global configuration file.
This step provides a layer of abstraction between your includeIf
statements
and your global Git configuration file. I find this useful if you plan to
share it, as it hides your on-disk file layout, and the different identities
you manage. It also allows for per-machine customization, if you plan to
re-use your global configuration file on more than one machine (e.g. your
personal and work machines, or several personal machines).
It's pretty simple: all it does is set up conditional include statements based on the path. Because we're organizing all of our work-related repositories into a single folder, this becomes pretty easy!
As an example, let's create a conditional statement for our "work" repositories.
[includeIf "gitdir:~/code/work/"]
path = ~/.config/git/config.work
The includeIf
statement here is stating that if we're in a git repository
(either at the root or in a subdirectory) within the ~/code/work
folder, then
a ~/.config/git/config.work
configuration file should be included.
Note
This file is created on each unique machine I use (I only have one laptop) and is backed up outside of my dotfiles repo.
Next, we need to create that ~/.config/git/config.work
configuration file.
Because this adds to your global configuration, you can set overrides here
(for example, for user.email
, user.signingkey
), or add entirely new
configuration properties (like aliases).
I'll leave the specific implementation up to you, but here's a quick example of what yours might look like:
[user]
name = John Doe
email = [email protected]
signingkey = ABCMYWORKSIGNINGKEY
Note
This will override any user.name
, user.email
, and user.signingkey
properties set earlier in your default global configuration file.