Contents
  1. The Three Scopes
  2. Reading Config Values
  3. Setting Values
  4. Essential Settings
  5. Identity
  6. Default branch name
  7. Default editor
  8. Auto-prune on fetch
  9. Push default
  10. Pull behaviour
  11. Line endings (important on Windows/Mac teams)
  12. Rerere (reuse recorded resolution)
  13. Colour output
  14. Aliases
  15. Conditional Includes
  16. The Config File Format
  17. Unsetting and Removing Values
  18. Quick Reference
← All posts

Git Config: How It Works and What to Set

A complete guide to git config — the three scopes, how values are resolved, the most useful settings, conditional includes for work vs personal machines, and how to inspect what is active.

The Three Scopes

Git config operates at three levels. Each level overrides the one above it.

ScopeFile locationFlag
System/etc/gitconfig--system
Global~/.gitconfig or ~/.config/git/config--global
Local.git/config inside the repo--local

System applies to every user on the machine. You rarely touch this.

Global applies to every repo for your user account. This is where you set your name, email, default editor, and personal preferences.

Local applies only to the current repository. It overrides global. Use it for per-project overrides, such as a different email for a work repo or a different default branch.


Reading Config Values

git config user.name                  # read a single value (local → global → system)
git config --global user.name         # read from global scope only
git config --list                     # list all active values (merged across scopes)
git config --list --show-origin       # same, but show which file each comes from
git config --list --show-scope        # same, but show scope name (local/global/system)

--list --show-origin is the most useful debugging tool. It tells you exactly which file is providing each value and lets you spot conflicts.


Setting Values

git config --global user.name "Brian"
git config --global user.email "you@example.com"
git config --local user.email "work@company.com"  # override for this repo only

To edit the config file directly in your editor:

git config --global --edit

Essential Settings

Identity

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

These appear in every commit you make. Without them, git uses system defaults which are often wrong.

Default branch name

git config --global init.defaultBranch main

Sets the branch name used when you run git init. Older git versions default to master.

Default editor

git config --global core.editor "code --wait"   # VS Code
git config --global core.editor "vim"
git config --global core.editor "nano"

Used for commit messages, interactive rebases, and merge conflict resolution when git opens an editor.

Auto-prune on fetch

git config --global fetch.prune true

Removes stale remote-tracking refs automatically every time you git fetch. Equivalent to always passing --prune.

Push default

git config --global push.default current

current pushes the current branch to a remote branch of the same name, creating it if it doesn’t exist. The older default (matching) pushed all branches that existed on both sides, which caused surprising behaviour.

Other options: simple (safe default since git 2.0), upstream, nothing.

Pull behaviour

git config --global pull.rebase false   # merge (default)
git config --global pull.rebase true    # rebase instead of merge
git config --global pull.ff only        # fast-forward only, fail otherwise

pull.ff only is the strictest. It refuses to pull if it can’t fast-forward, forcing you to rebase or merge manually. Good for keeping history clean.

Line endings (important on Windows/Mac teams)

git config --global core.autocrlf input   # Mac/Linux: convert CRLF to LF on commit
git config --global core.autocrlf true    # Windows: convert LF to CRLF on checkout

Rerere (reuse recorded resolution)

git config --global rerere.enabled true

Remembers how you resolved a merge conflict and reapplies the same resolution automatically if the same conflict appears again. Useful on long-running branches that frequently rebase onto main.

Colour output

git config --global color.ui auto

Enables coloured output in terminal when output goes to a terminal (not a pipe). Usually the default, but worth setting explicitly.


Aliases

Aliases let you define shorthand for commands you type frequently.

git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.lg "log --oneline --graph --all"
git config --global alias.unstage "reset HEAD --"
git config --global alias.last "log -1 HEAD"

After setting these:

git st        # git status
git lg        # pretty log graph
git unstage src/foo.ts  # unstage a file

Aliases can also run shell commands by prefixing with !:

git config --global alias.aliases "config --get-regexp alias"
# git aliases → lists all your aliases

Conditional Includes

If you use one machine for both personal and work projects, conditional includes let you automatically apply a different config depending on where the repo lives.

In ~/.gitconfig:

[includeIf "gitdir:~/personal/"]
  path = ~/.gitconfig-personal

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

~/.gitconfig-personal:

[user]
  email = personal@gmail.com

~/.gitconfig-work:

[user]
  email = brian@company.com
  signingKey = ABCD1234

The gitdir: condition matches based on the .git directory path of the current repo. If a repo is inside ~/work/, the work config is included and its values override the global ones.

You can also match on the remote URL with hasconfig:remote.*.url::

[includeIf "hasconfig:remote.*.url:git@github.com:mycompany/*"]
  path = ~/.gitconfig-work

The Config File Format

The .gitconfig file is INI-style. Sections are in brackets, keys are indented under them.

[user]
  name = Brian
  email = you@example.com

[core]
  editor = code --wait
  autocrlf = input

[alias]
  lg = log --oneline --graph --all
  st = status

[fetch]
  prune = true

[pull]
  rebase = false

You can edit this directly. It’s just a text file. git config --global --edit opens it in your configured editor.


Unsetting and Removing Values

git config --global --unset user.email         # remove a specific key
git config --global --remove-section alias     # remove an entire section

Quick Reference

TaskCommand
See all active config with sourcegit config --list --show-origin
Set global identitygit config --global user.name / user.email
Override email for one repogit config --local user.email "work@co.com"
Edit global config in editorgit config --global --edit
Auto-prune on fetchgit config --global fetch.prune true
Add an aliasgit config --global alias.lg "log --oneline --graph"
Remove a valuegit config --global --unset <key>
← All posts