Install and Config¶
Git reads settings from three files layered by scope, and the first commit needs only an identity set at the global level. Interviewers ask about config to check that a candidate knows the system, global and local order and can set a per-directory identity, because a wrong committer email is a common and annoying mistake.
Track: Core · Interview weight: Med
Must-Know Facts¶
| Fact | Value | Verify with |
|---|---|---|
| System scope | /etc/gitconfig, all users; git config --system | git config --show-scope --list |
| Global scope | ~/.gitconfig, one user; git config --global | git config --global --list |
| Local scope | .git/config, one repository; git config --local | git config --local --list |
| Precedence | Local overrides global overrides system | git config --show-origin <key> |
| Identity | user.name and user.email, stamped into every commit | git config user.email |
| Default branch | init.defaultBranch, main on current Git | git config init.defaultBranch |
| Editor | core.editor, for commit messages and rebases | git config core.editor |
| Alias | git config --global alias.<name> "<command>" | git config --get-regexp alias |
| Per-directory | includeIf "gitdir:~/work/" includes another config file | git config --show-origin user.email |
| Read one value | git config --get <key> | the value |
Installing Git¶
Git ships as a single package on every platform. Confirm the version after installing, because a few features named in these notes (git switch, git restore, SHA-256 repositories) depend on a recent build.
brew install git # macOS with Homebrew
sudo apt install git # Debian and Ubuntu
sudo dnf install git # RHEL, Rocky and Fedora
git --version
winget install --id Git.Git
git --version
Output:
git version 2.50.1 (Apple Git-155)
The Three Config Scopes¶
Settings live in three files, and a lookup returns the value from the most specific scope that has it. System applies to every user, global to one user, and local to a single repository.
git config --global user.name "Amina Yusuf"
git config --global user.email "amina@example.com"
git config --global init.defaultBranch main
git config --global core.editor "vim"
git config --global pull.rebase true
None of those print output; each writes a line into ~/.gitconfig. Listing the file with the origin of each value confirms where a setting came from.
git config --list --show-origin --global
Output:
file:/home/amina/.gitconfig user.name=Amina Yusuf
file:/home/amina/.gitconfig user.email=amina@example.com
file:/home/amina/.gitconfig init.defaultbranch=main
file:/home/amina/.gitconfig core.editor=vim
file:/home/amina/.gitconfig pull.rebase=true
Keys are stored lowercased in the section (init.defaultbranch), which is why config keys are case-insensitive in the section and name but case-sensitive in the value.
System scope needs root, and a local override hides a global identity
git config --system writes /etc/gitconfig and needs sudo, so most user settings go in global. A user.email set locally in one repository silently overrides the global one, which is the usual reason commits on a single project carry the wrong address.
Precedence and Reading a Value¶
A local setting in .git/config overrides the same key set globally, so a repository can carry a different committer email than the user default.
git config --local user.email "amina@work.example.com"
git config user.email
Output:
amina@work.example.com
git config --show-scope --get-all <key> shows every scope that defines a key, which is the fastest way to explain a surprising value.
git config --show-scope --get-all user.email
Output:
global amina@example.com
local amina@work.example.com
The lookup returns the local value because local is more specific than global. git config --get <key> reads the single effective value for scripts.
Per-Directory Identity with includeIf¶
includeIf pulls in another config file only when the repository path matches, which sets a work email for everything under ~/work/ without editing each repository.
cat >> ~/.gitconfig <<'EOF'
[includeIf "gitdir:~/work/"]
path = ~/work/.gitconfig-work
EOF
git config --get includeIf.gitdir:~/work/.path
Output:
~/work/.gitconfig-work
The included file holds the overriding user.email. The gitdir: pattern must end with a slash to match a directory tree, and the include is evaluated by the path of the repository Git is operating in.
Aliases shorten a long command to a single word
git config --global alias.lg "log --oneline --graph --decorate" makes git lg run the full command. An alias starting with ! runs a shell command instead of a Git subcommand, which is how aliases call external scripts.
Common Errors¶
Author identity unknown and Please tell me who you are¶
Cause: user.name or user.email is unset in every scope, so Git cannot stamp a committer onto the commit.
Fix: set them globally with git config --global user.email "you@example.com" (and user.name), or locally for one repository.
error: key does not contain a section: name¶
Cause: a git config key was given without a section, such as git config name instead of git config user.name.
Fix: use the full section.key form, for example git config user.name.
Interview Checkpoints¶
L1: What are the three config scopes and their order of precedence?
Say first: system (/etc/gitconfig, all users), global (~/.gitconfig, one user) and local (.git/config, one repository); local overrides global, which overrides system.
Proof: git config --show-origin user.email names the file the effective value came from.
Follow-up: How do you give one repository a different committer email from your default?
L1: Where does Git get the name and email it puts on a commit?
Say first: from user.name and user.email, resolved through the scope precedence, with the local repository value winning if set.
Proof: git config user.email prints the effective value; git config --show-scope --get-all user.email shows every scope that defines it.
Follow-up: What does Git do if neither is set anywhere?
L2: Set your identity globally but override the email for all repositories under ~/work.
Say first: set the global identity, then add an includeIf "gitdir:~/work/" block pointing at a work config file that redefines user.email.
Proof:
git config --global user.email "amina@example.com"
git config --show-origin user.email # from ~/work run inside a work repo
Follow-up: Why must the gitdir: pattern end with a slash?
L2: Create an alias so git lg shows a decorated one-line graph.
Say first: git config --global alias.lg "log --oneline --graph --decorate".
Proof: git config --get-regexp alias lists the alias; git lg runs the expansion.
Follow-up: How would you make an alias that runs a shell command rather than a Git subcommand?
L3: A colleague's commits show the wrong email on one project only. Where do you look?
Say first: a local override in that repository's .git/config is winning over their global identity.
Proof: git config --show-scope --get-all user.email lists both scopes; the local line is the culprit.
Follow-up: How would you fix the commits that already carry the wrong email?
L4: How does Git decide which config file a value comes from?
Say first: it reads system, then global (with any includeIf files spliced in where they match), then local, later files overriding earlier keys, so the last write to a key in precedence order wins.
Proof: git config --list --show-origin prints every value with its source file in read order.
Don't say: "Local and global are merged and the alphabetically first wins."
Related¶
- What Is Git: why every commit carries a committer identity
- The Three Trees: the areas the first commit moves a change through
- Staging and Committing: the identity every commit records, in use
- Error Messages: the identity and config errors, with fixes
Captured on macOS 26 with git 2.50.1 (throwaway local repositories), 2026-09.