Progress:
TIER 2 · MODULE 01· Intermediate

git config

Layered config: system, global, local, worktree. Learn the layers.

🎯 What & why

git config reads and writes the key/value store that controls every knob in Git, from your name on commits to whether pull rebases. It is the single source of truth for Git's behavior; learn the layers or be confused forever.

🧠 Mental model

Pure text files. Nothing in the working tree, index, objects, or refs is touched. Config lives in plain INI-style files at four scopes (system, global, local, worktree) and is merged with later scopes overriding earlier ones at lookup time.

🛠️ Synopsis

git config [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] name [value [value-pattern]]
git config [<file-option>] [--type=<type>] --add name value
git config [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] --get name [value-pattern]
git config [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] --get-all name [value-pattern]
git config [<file-option>] [--type=<type>] [--show-origin] [--show-scope] [-z|--null] --get-regexp name_regex [value-pattern]
git config [<file-option>] --unset name [value-pattern]
git config [<file-option>] --unset-all name [value-pattern]
git config [<file-option>] --rename-section old_name new_name
git config [<file-option>] --remove-section name
git config [<file-option>] [--show-origin] [--show-scope] [-z|--null] -l | --list
git config [<file-option>] --get-color name [default]
git config [<file-option>] --get-colorbool name [stdout-is-tty]
git config [<file-option>] -e | --edit

🎚️ Switches & options

FlagWhat it does
--systemEdit /etc/gitconfig. Affects every user on the box.
--globalEdit ~/.gitconfig (or ~/.config/git/config). Per-user, normal default for personal settings.
--localEdit .git/config. Per-repo, default if you give no scope flag inside a repo.
--worktreeEdit per-worktree config. Requires extensions.worktreeConfig=true.
--addAppend a new line for a multi-value key instead of replacing it.
--replace-all⚠️ Force a single value for a key that has multiple lines. Will silently nuke the others.
--get-regexpDump all keys matching a regex. The right tool for finding what's set.

📦 Subcommands

--get <key> — Print the value of <key> (highest-precedence layer wins).
$ git config --get user.email
--set <key> <value> — Implicit form (git config <key> <value>); writes to local scope by default.
$ git config user.email you@example.com
--unset <key> — Remove a single value of <key>.
$ git config --unset user.email
--add <key> <value> — Append another value (for multi-valued keys like remote.<name>.url).
$ git config --add remote.origin.url git@mirror:proj.git
--list [--show-scope] [--show-origin] — Dump all settings; with --show-origin shows which file each came from.
$ git config --list --show-origin
--get-regexp <pattern> — Find all keys matching <pattern>.
$ git config --get-regexp '^alias\.'
--edit — Open the chosen scope's config in $EDITOR.
$ git config --global --edit
--remove-section <section> — Drop a whole [section] block.
$ git config --remove-section alias

💡 Use cases

🧪 Examples

Set identity globally
$ git config --global user.name "Linus T."
$ git config --global user.email "torvalds@example.org"
$ git config --global init.defaultBranch main
$ git config --global pull.rebase true
Find where a value comes from
$ git config --show-origin --show-scope --get user.email
# global  file:/home/you/.gitconfig    you@personal.tld
$ git config --show-origin --get-all remote.origin.fetch
Conditional include for work repos
# in ~/.gitconfig
[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work
# then ~/.gitconfig-work
[user]
    email = you@bigcorp.com
Define an alias
$ git config --global alias.lg "log --oneline --graph --decorate --all"
$ git lg

🎓 Recommendations

🪤 Common pitfalls

🔗 Related modules

📝 Quiz

Hit each option, then Check answers. Score is recorded; Next is always open.