Git Course 0%

Configuration deep dive

Expert Git CLI ≈ 12 min

Before this lesson

What you will learn

  • How to find out where a setting came from
  • Aliases that are worth the muscle memory
  • includeIf, which sets your identity by folder

After this lesson you can

  • My Git is configured deliberately, and my work and personal identities cannot be mixed up

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

Terminal
$ git config --list --show-origin | grep user
file:~/.gitconfig	user.name=You
file:~/.gitconfig	user.email=you@example.com

Or for one setting:

Terminal
$ git config --show-origin --get user.email
file:~/dev/work.gitconfig	ana@northwind-trails.example

Levels, 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:

~/.gitconfig
[user]
	name = Your Name
	email = you@personal.example

[includeIf "gitdir:~/dev/work/"]
	path = ~/dev/work/.gitconfig-work
~/dev/work/.gitconfig-work
[user]
	name = Ana Lopez
	email = ana@northwind-trails.example

Then, inside a repository under ~/dev/work/:

Terminal
$ git config --get user.email
ana@northwind-trails.example

And anywhere else:

Terminal
$ git config --get user.email
you@example.com

Three 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

Terminal
$ 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 project

A few worth having, chosen because they are the ones people type dozens of times a day:

~/.gitconfig
[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-lease

pushf 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:

Terminal
$ git config user.email "ana@northwind-trails.example"
$ git config --show-origin --get user.email

How to do it

Terminal
$ 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.

Common mistakes

  • Setting the identity per repository by hand and forgetting on the next clone. includeIf is 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.autocorrect left on, which runs a command you did not type.
  • Editing .git/config while a Git command is running.

Try it yourself

Goal: make it impossible to commit with the wrong identity.

  1. Run git config --list --show-origin and read where your current settings come from.
  2. Create two folders, say ~/dev/work/ and ~/dev/personal/, and move or clone a repository into each.
  3. Add an includeIf block to ~/.gitconfig pointing at a work-specific file that sets user.email.
  4. In each repository, run git config --show-origin --get user.email and confirm the values differ and the origins are the files you expect.
  5. 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.

Check yourself

1. How do you find out which file a setting came from?
2. What does includeIf "gitdir:~/dev/work/" do?
3. Which alias is worth having for safety?

Key terms

Configuration Environment variable Repository (repo)