blog::weyl.io

Chris Weyl's Technical Blog

Conditional git Configuration

git has always(?) allowed for the additional configuration files to be unconditionally included:

[include]
    path = path/to/gitconfig

Each individual git repo has always had the ability to maintain its own configuration at .git/config. However, sometimes on our systems we also have certain locations where we store multiple git projects, which may need different configuration from the global, but still common across that location.

Since ... well, for the last year or two at least, git has allowed for the conditional inclusion of configuration files.

For example, I contribute to F/OSS projects using one email address, which lives in my global git config (~/.config/git/config, in my case). However, for work projects, I want to use my work email everywhere — and accidentally pushing w/my personal email address is just embarrassing. All of my work projects live under a certain directory, so I can tell git that if a given repository's gitdir lives under ~/work, it should also load an additional configuration file:

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

...and in there, I can set

; this is ~/work/gitconfig
[user]
    email = cweyl@work.com

In this way, I do not need to remember to change the email address of any repos I clone under ~/work to my work address. This is especially useful as I not infrequently find myself forking and submitting bugfix PR/MR's to upstream, and if I do that for $work then I want to be using my work email address.

See also the "Includes" and "Conditional Includes" sections of the git-config manpage.


Useful systemwide git defaults -- revisited

A while back, I wrote about "useful git defaults". This is a tricky subject, as a sufficiently aged ~/.gitconfig is much like a vimrc or Chief O'Brien's rank: a very religious topic.

Nonetheless, it's one of those things where a few small adjustments to the system-wide git configuration (a la /etc/gitconfig) can make things much, much easier — particularly in the case where there are multiple systems to manage, and multiple people using them.

I'm pretty happy with those defaults, but a lot has changed since 2014.

git config file locations

The configuration paths available have also changed:

To do this, we can leverage the little-used system-wide git config file at /etc/gitconfig. Remember that by default git looks at four files to determine its configuration (in ascending order of priority):

  1. /etc/gitconfig (system),
  2. ~/.config/git/config,
  3. ~/.gitconfig (user aka global), and
  4. .git/config (configuration for the current repository).

(Technically, #2 is $XDG_CONFIG_HOME/git/config.)

This allows us to set defaults in the system configuration file without interfering with people who prefer different settings: their global config at ~/.gitconfig will win.

/etc/gitconfig

For our purposes, we're talking about settings in /etc/gitconfig, though they can certainly be used in other places as well.

This config sets a couple safer defaults for pushing, makes git merge/diff/rebase a little more DWIM, causes the committer, as well as the author, information to be displayed by default, as well as allowing for an easy way to override the system config on a per-system basis. (In case, say, you're using puppet or the like to distribute this configuration across multiple hosts.)

Note that we do not do some things that individuals may wish to do, as we're aiming for "unobtrusive, reasonable universal defaults", e.g. rebase.autosquash is not set to true. (Though the author highly recommends this setting.)


Useful git defaults -- systemwide

Sometimes it's necessary to -- for one's sanity, if nothing else -- to establish a set of generally non-controversial, sane, system-wide git configuration defaults. This is largely helpful when multiple people are using the same system who may not have a standard ~/.gitconfig they carry around with them.

To do this, we can leverage the little-used system-wide git config file at /etc/gitconfig. Remember that by default git looks at three files to determine its configuration (in ascending order of priority):

  1. /etc/gitconfig (system),
  2. ~/.gitconfig (user aka global), and
  3. .git/config (configuration for the current repository).

This allows us to set defaults in the system configuration file without interfering with people who prefer different settings: their global config at ~/.gitconfig will win.

This config sets a couple safer defaults for pushing, makes git merge/diff/rebase a little more DWIM, causes the committer, as well as the author, information to be displayed by default, as well as allowing for an easy way to override the system config on a per-system basis. (In case, say, you're using puppet or the like to distribute this configuration across multiple hosts.)

And... As with all things "generally non-controversial", remember that these are the sorts of things likely to touch off religious wars. The goal here is for a sane set of defaults for all users, not The One True Way To Do GIT. That's what user global configs are for :)