Git and libgit2

Git Configuration

Published 2023-05-30. Last modified 2023-10-06.
Time to read: 3 minutes.

This page is part of the git collection.

This article is not meant to be exhaustive. These are just my notes about global settings that I use.

Global Configuration File

~/.gitconfig contains an OS user’s global settings. These settings are normally maintained by using the git config ‑‑global command, but the file could also be modified using a text editor.

~/.gitconfig
[branch "master"]
  remote = origin
  merge = refs/heads/master
[core]
  filemode = false
  autocrlf = input
  safecrlf = false
  pager = less -F
[color]
  status = auto
  branch = auto
  ui = auto
[gui]
  trustmtime = true
[push]
  default = matching
  autoSetupRemote = true
  autoSetupRemote = true
[user]
  name = Mike Slinn
  email = mslinn@mslinn.com
[rebase]
  autostash = true
[diff "exif"]
  textconv = exiftool
[diff]
  compactionHeuristic = true
  colorMoved = zebra
[init]
  defaultBranch = master
[pull]
  rebase = true
[fetch]
  prune = true

Config Commands

The following commands created some of the above settings.

Shell
$ git config --global pull.rebase true

$ git config --global fetch.prune true

$ git config --global diff.colorMoved zebra

For an explanation of the above settings, please see Three Git Configurations that Should Be the Default.

Shell
$ git config --global rebase.autostash true

For an explanation of the above setting, please see this git tip by Chi Shang Cheng.

For an explanation of the core.pager setting, please see The Git Pager.

Configuring Garbage Collection

Some git commands automatically run git gc according to various configuration parameters. Although you can permanently disable this behavior, I do not recommend that you normally do this. However, if you need to preserve the state of a repository, perhaps to prepare a repository to be used as evidence in a legal proceeding, then this would be necessary.

Following are two equivalent syntaxes. Note that these commands only operate on the current git project. I do not advise making these settings global.

Shell
$ git config gc.auto never

$ git config gc.auto 0

Environment Variables

If you do not want to type merge comments, you can either use the --noedit option each time you run git merge, like this:

Shell
$ git merge --no-edit

Or you can define a bash alias, like this:

Shell
alias git.merge='git merge --no-edit'

Or you can add the following to ~/.bashrc:

Shell
export GIT_MERGE_AUTOEDIT=no

Reflog Configuration

The reflog records the change history of blobs (files); it contains all changes to a repository. Some commands that change a git repository’s history include:

Git never changes existing commits; instead of editing a commit, the old commit is moved from the branch history to the reflog, and a new commit is created. The reflog is a way to explore a git repository's change history. The reflog also makes it possible to undo a destructive operation.

Stashes are implemented using the reflog, which means that they do not normally persist forever. Instead, their maximum lifespan is set by the gc.reflogExpire configuration setting, described next.

Reflog Configuration for Reachable Commits

The default length of time that blobs that are reachable from a branch, or another HEAD such as a stash, are allowed to persist in the reflog is 90 days. After this time they are subject to garbage collection the next time one of several git commands runs. This time period value can be modified with the gc.reflogExpire configuration setting.

Unfortunately, the default value is not displayed when queried; you need to know that you should interpret the following lackof response to mean 90 days:

Shell
$ git config gc.reflogExpire

Various time intervals can be used, for example days, weeks, months, years and never. The default time interval is days. Let’s change the default expiry period to 3 days, then query it:

Shell
$ git config gc.reflogExpire 3

$ git config gc.reflogExpire
3 

We can display the changes to .git/config that resulted from the above command as follows:

Shell
$ awk '/\[gc\]/{f=1}f' .git/config
[gc]
        reflogExpire = 3 

The following shows 3 syntaxes, all of which change the value for the current repository to expire after 3 days:

Shell
$ git config gc.reflogExpire 3

$ git config gc.reflogExpire 3.days

$ git config gc.reflogExpire '3 days'

Other units can be specified, and two syntaxes are supported:

Shell
$ git config gc.reflogExpire 3.weeks

$ git config gc.reflogExpire '3 weeks'

$ git config gc.reflogExpire 3.months

$ git config gc.reflogExpire '3 months'

$ git config gc.reflogExpire '3 years'

$ git config gc.reflogExpire 3.years

You can change gc.reflogExpire to never expire; however, be warned that this will cause your local copy of the git repository to grow without bounds, which will eventually cause your computer to grind very slowly every time you perform an operation on the repository.

Shell
$ git config gc.reflogExpire never

You can change the value for the current repository to expire immediately as follows. Because this is a permanent setting, this actually means that you do not want a reflog; which implies that the git stash command will be disabled, and refs that rely on the reflog will not be available.

Shell
$ git config gc.reflogExpire now

$ awk '/\[gc\]/{f=1}f' .git/config
[gc]
        reflogExpire = now 

Reflog Configuration for Dangling Commits

gc.reflogExpireUnreachable is used to set how long dangling commits should be preserved. This value defaults to 30 days.

As with the gc.reflogExpire configuration, it is again unfortunate that the default value for gc.reflogExpireUnreachable is not displayed when queried. You need to know that the following lack of response means 30 days, not 90 days as is the case for gc.reflogExpire:

Shell
$ git config gc.reflogExpire

The same time span syntax is used for gc.reflogExpire and gc.reflogExpireUnreachable, including the values now and never. Following is an example of setting the time span to 13 days:

Shell
$ git config gc.reflogExpireUnreachable 13

$ awk '/\[gc\]/{f=1}f' .git/config
[gc]
        reflogExpireUnreachable = 13 
* indicates a required field.

Please select the following to receive Mike Slinn’s newsletter:

You can unsubscribe at any time by clicking the link in the footer of emails.

Mike Slinn uses Mailchimp as his marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp’s privacy practices.