Config Layers

Updated

October 30, 2026

Config Layers

After this page you can say which file a Git setting comes from, and set the handful of keys this book assumes.

Three layers

Layer Flag Typical file Who
System --system /etc/gitconfig every user on the machine
Global --global ~/.gitconfig you, every repo
Local --local (default) .git/config this repo only

Later keys override earlier ones. Work email in a company repo is a local user.email, not a second global identity you forget to switch.

  wins
    ▲
    │   .git/config          local    this repo
    │   ~/.gitconfig         global   this user
    │   /etc/gitconfig       system   this machine
    │
  reads bottom → top; last value for a key wins
git config --list --show-origin --show-scope
git config --show-origin user.email

--show-origin prints the file that won. --unset removes a key at the layer you name:

git config --global --unset core.editor

Set the global layer once

git config --global init.defaultBranch main
git config --global core.editor "nvim"
git config --global pull.ff only
git config --global rerere.enabled true
git config --global diff.algorithm histogram
git config --global merge.conflictstyle zdiff3
Key Why
init.defaultBranch main git init creates main, not master
core.editor git commit without -m opens this editor (code --wait, vim, nvim)
pull.ff only git pull fast-forwards or fails; you merge or rebase on purpose
rerere.enabled reuse recorded conflict resolutions
diff.algorithm histogram better diffs on refactored files
merge.conflictstyle zdiff3 conflict markers include the common ancestor

pull.ff only means a pull that would create a merge commit fails instead. That is safer than the old default. Chapter 11 is remotes; this setting is safe to apply now.

Leave core.fileMode at the default so Git records executable bits. Set it to false only on a filesystem that cannot store those bits.

Repo-only overrides

cd desk-api
git config user.email "ada@work.example"
# writes .git/config

Inspect:

git config --local --list --show-origin

includeIf for home vs work

# ~/.gitconfig
[user]
    name = Ada Desk
    email = ada@example.com

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work
# ~/.gitconfig-work
[user]
    email = ada@work.example

Any repo under ~/work/ picks up the work email without a per-repo command. Paths in gitdir: should be absolute or start with ~/.

See the result

git config --list --show-origin --show-scope | less

Identity (user.name, user.email) is the next page. Those two keys go into every commit.