Configuration deep dive
Expert Git CLI
Why this matters
Two problems this solves. The first is "why is this setting what it is?", which --show-origin answers in one line. The second is committing to a work repository with a personal address, which includeIf prevents permanently.
Where a setting comes from
$ git config --list --show-origin | grep userfile:~/.gitconfig user.name=You
file:~/.gitconfig user.email=you@example.comOr for one setting:
$ git config --show-origin --get user.emailfile:~/dev/work.gitconfig ana@northwind-trails.exampleLevels, from weakest to strongest (lesson 3.4):
| Level | File | Flag |
|---|---|---|
| System | /etc/gitconfig |
--system |
| Global (you) | ~/.gitconfig |
--global |
| Local (this repository) | .git/config |
--local |
| Worktree | .git/config.worktree |
--worktree |
| One command | — | git -c user.email=… |
The later ones win. The worktree level exists for lesson 18.6 and is rarely needed otherwise.
includeIf: identity by folder
The reliable fix for two identities on one machine. In ~/.gitconfig:
[user]
name = Your Name
email = you@personal.example
[includeIf "gitdir:~/dev/work/"]
path = ~/dev/work/.gitconfig-work[user]
name = Ana Lopez
email = ana@northwind-trails.exampleThen, inside a repository under ~/dev/work/:
$ git config --get user.emailana@northwind-trails.exampleAnd anywhere else:
$ git config --get user.emailyou@example.comThree details that trip people up:
- The trailing slash matters.
gitdir:~/dev/work/matches everything inside; without it the match is exact. - The path is relative to the file doing the including, so absolute paths or
~are safest. - It matches the repository's location, not the remote. Sorting your folders by employer is what makes it work.
includeIf can carry more than identity: signing keys, a different SSH command, different aliases (lesson 18.3).
Aliases
$ git config --global alias.lg "log --oneline --graph -10"
$ git lg* d3b92ec chore: add CI configuration and contributing guide
* b81702c docs: add getting started guide and FAQ
* 28593d2 feat: add the trail list command
* e653def chore: start the trailguide projectA few worth having, chosen because they are the ones people type dozens of times a day:
[alias]
st = status -sb
lg = log --oneline --graph --decorate -20
last = log -1 --stat
unstage = restore --staged
pushf = push --force-with-lease
wip = commit -am "wip"
please = push --force-with-leasepushf earns its place by keeping the dangerous spelling out of your fingers (lesson 12.8).
An alias starting with ! runs a shell command instead of a Git subcommand, which is powerful and worth using sparingly, since it stops being portable.
Settings worth knowing
| Setting | Does |
|---|---|
pull.rebase = false or true |
Whether git pull merges or rebases (lesson 7.5) |
push.default = simple |
Push only the current branch to its upstream |
push.autoSetupRemote = true |
A first push sets the upstream without -u |
merge.conflictstyle = zdiff3 |
Conflict markers include the base (lesson 11.2) |
rerere.enabled = true |
Remember conflict resolutions (lesson 18.7) |
core.autocrlf |
Line endings; prefer .gitattributes instead (lesson 4.5) |
fetch.prune = true |
Fetch removes remote-tracking branches that are gone |
init.defaultBranch = main |
New repositories start on main |
diff.algorithm = histogram |
Slightly better diffs, at no cost you will notice |
help.autocorrect |
Runs the command it thinks you meant; set it to 0 unless you enjoy surprises |
Per-repository overrides
Inside a repository, git config user.email … writes to .git/config and beats the global. That is the manual version of includeIf, useful for the one repository that does not fit your folder layout:
$ git config user.email "ana@northwind-trails.example"
$ git config --show-origin --get user.emailHow to do it
$ git config --list --show-origin
$ git config --show-origin --get <key>
$ git config --global --edit
$ git config --global alias.st "status -sb"--edit opens the file in your editor, which is easier than a dozen git config calls for a first-time setup.
No configuration interface for Git itself; VS Code's own settings are separate (lesson 15.1). Use the integrated terminal, or open ~/.gitconfig as a file.
Settings → Version Control → Git exposes a few options; the rest is ~/.gitconfig. IntelliJ respects includeIf because it runs the same binary.
Nothing here is platform configuration. The platform equivalent of an identity check is the verified-email list on your profile (lesson 9.1).
The same (lesson 10.1).
Common mistakes
- Setting the identity per repository by hand and forgetting on the next clone.
includeIfis the fix. - Omitting the trailing slash in a
gitdir:condition. - A relative include path, which resolves against the including file and surprises people.
- Aliases that hide danger, such as one for
push --force. help.autocorrectleft on, which runs a command you did not type.- Editing
.git/configwhile a Git command is running.
Try it yourself
Goal: make it impossible to commit with the wrong identity.
- Run
git config --list --show-originand read where your current settings come from. - Create two folders, say
~/dev/work/and~/dev/personal/, and move or clone a repository into each. - Add an
includeIfblock to~/.gitconfigpointing at a work-specific file that setsuser.email. - In each repository, run
git config --show-origin --get user.emailand confirm the values differ and the origins are the files you expect. - Add three aliases you would actually use, including
pushf = push --force-with-lease.
Expected result: the same command returning different identities in two folders, with the source of each visible.
Show solution
Step 4 is the confirmation that matters. --show-origin names the file, so if the include is not matching you can see that immediately rather than discovering it in a commit's author field a week later. The most common cause is a missing trailing slash on the gitdir: path.