|$ curl https://forge-ai.dev/api/markdown?path=docs/git/config
$cat docs/git-config.md
updated Today·22-30 min read·published

Git Config

GitConfigBeginner🎯Free Tools
Introduction

Git config is layered: system, global, local, worktree, and command-line overrides. Understanding precedence prevents 'why is my setting ignored?' mysteries.

Scopes & Precedence
ScopeFlagTypical file
system--system/etc/gitconfig
global--global~/.gitconfig
local--local (default).git/config
worktree--worktree.git/config.worktree
command-c key=valueephemeral
scopes.sh
Bash
1git config --list --show-origin | head -40
2git config --list --show-scope | head -40
3git config --global user.name "Jane Doe"
4git config --local user.email "jane@work.com"
5git -c user.name="CI Bot" commit -m "chore: ci"
Identity Settings
identity.sh
Bash
1git config --global user.name "Jane Doe"
2git config --global user.email "jane@example.com"
3git config --global author.name "Jane Doe"
4git config --global author.email "jane@example.com"
5# Conditional identity per directory — see includes below
Useful Settings
useful.sh
Bash
1git config --global init.defaultBranch main
2git config --global pull.rebase true
3git config --global fetch.prune true
4git config --global rebase.autoStash true
5git config --global diff.colorMoved zebra
6git config --global merge.conflictstyle diff3
7git config --global core.editor "code --wait"
8git config --global core.autocrlf input # mac/linux
9git config --global help.autocorrect 20
10git config --global push.autoSetupRemote true
11git config --global rerere.enabled true
12git config --global column.ui auto
13git config --global branch.sort -committerdate
KeyWhy
pull.rebase trueAvoid merge bubbles on pull
fetch.prune trueDrop deleted remote branches
rebase.autoStash trueStash dirty tree during rebase
rerere.enabled trueReuse recorded conflict resolutions
push.autoSetupRemote trueSimpler first push
Includes & Conditional Includes

Split config across files and apply settings only under certain paths or remotes.

gitconfig
INI
1[user]
2 name = Jane Doe
3 email = personal@example.com
4
5[include]
6 path = ~/.config/git/aliases.gitconfig
7
8[includeIf "gitdir:~/work/"]
9 path = ~/.config/git/work.gitconfig
10
11[includeIf "hasconfig:remote.*.url:git@github.com:myorg/**"]
12 path = ~/.config/git/myorg.gitconfig
work.gitconfig
INI
1[user]
2 email = jane@company.com
3[commit]
4 gpgsign = true
Alias Section

Deep dive: Aliases.

aliases.ini
INI
1[alias]
2 st = status -sb
3 co = switch
4 br = branch -vv
5 lg = log --oneline --graph --decorate --all
6 last = log -1 --stat
7 unstage = restore --staged
8 amend = commit --amend --no-edit
Credential Helpers
cred.sh
Bash
1git config --global credential.helper cache --timeout=28800
2# macOS
3git config --global credential.helper osxkeychain
4# Windows
5git config --global credential.helper manager
6# GitHub CLI as helper
7gh auth setup-git
Inspect & Unset
inspect.sh
Bash
1git config --get user.email
2git config --get-regexp '^alias\.'
3git config --unset --global pull.rebase
4git config --global -e # open editor
Hands-on Lab

Prove precedence with a disposable repo.

lab-config.sh
Bash
1mkdir -p /tmp/git-config-lab && cd /tmp/git-config-lab
2git init -b main
3git config --local user.email "local@example.com"
4echo "global would be overridden by local"
5git config --get user.email
6git config --list --show-origin | grep user.email || true
7git -c user.email="override@example.com" var GIT_AUTHOR_IDENT
FAQ

Common questions.

Local vs global email?

Local wins for that repo — useful for work vs personal.

Where is my config?

git config --list --show-origin

How do I reset a key?

git config --unset [--global] key

Notes for AI Agents
  • Prefer --show-origin when debugging
  • Do not write secrets into gitconfig
  • Use includeIf for work email separation
  • Document required local configs in CONTRIBUTING
🔥

pro tip

Curriculum: How to Master Git.
Worked Examples

These end-to-end examples reinforce the config concepts above. Run them in a disposable lab under /tmp so mistakes are cheap.

Example A — happy path

example-a.sh
Bash
1# Lab for config
2rm -rf /tmp/git-lab-config && mkdir -p /tmp/git-lab-config
3cd /tmp/git-lab-config
4git init -b main
5git config user.email "lab@example.com"
6git config user.name "Lab User"
7echo "# lab" > README.md
8git add README.md
9git commit -m "chore: init lab for config"
10git status -sb
11git log --oneline --decorate

Example B — recover from a mistake

example-b.sh
Bash
1# Make a bad commit, then recover safely
2echo bad > oops.txt
3git add oops.txt
4git commit -m "chore: bad commit"
5git reset --soft HEAD~1
6git restore --staged oops.txt
7rm oops.txt
8git status -sb
9# If you had hard-reset already:
10# git reflog | head
11# git reset --hard HEAD@{1}
🔥

pro tip

Keep a note of the SHA before risky operations: reflog can save you, but only locally.
Troubleshooting

Symptoms you will hit in real repos, and the first commands to run.

Unexpected dirty tree

trouble-dirty.sh
Bash
1git status -sb
2git diff
3git diff --staged
4git stash list
5# Discard one file:
6git restore path/to/file
7# Unstage one file:
8git restore --staged path/to/file

Diverged from remote

trouble-diverge.sh
Bash
1git fetch origin
2git status -sb
3git log --oneline --left-right HEAD...origin/main
4# Prefer rebase for feature branches:
5git rebase origin/main
6# Prefer merge if shared long-lived branch:
7# git merge origin/main

Conflict markers left behind

trouble-markers.sh
Bash
1git diff --check
2rg -n '^(<<<<<<<|=======|>>>>>>>)' || true
3# Fix files, then:
4git add -A
5git status

danger

Never force-push to main to "fix" divergence. Use revert or a forward fix.
Command Cheatsheet

Keep this short list nearby while practicing config.

cheatsheet.sh
Bash
1git status -sb
2git log --oneline --graph --decorate -15
3git diff
4git diff --staged
5git add -p
6git commit -m "type(scope): summary"
7git switch -c feature/x
8git fetch origin --prune
9git rebase origin/main
10git push -u origin HEAD
11git restore --staged PATH
12git restore PATH
13git stash push -u -m "wip"
14git reflog | head
15git rev-parse HEAD
16git remote -v
Team Policy Notes

Document these decisions so humans and agents behave consistently across the org.

  • Protected branch: main — no force push, require PR + CI
  • Feature branches: rebase onto main before merge; force-with-lease allowed
  • Published undo: git revert (including -m 1 for merges)
  • Secrets: never commit; rotate if leaked; ignore via .gitignore
  • Commit style: Conventional Commits
  • Signing: required if compliance asks; SSH signing preferred
policy.md
Markdown
1# Git policy (excerpt)
2- defaultBranch: main
3- updateStrategy: rebase
4- mergeStrategy: squash (via host)
5- allowForcePush: feature/* only with --force-with-lease
6- requireSignedCommits: true
7- maxPRLines: 400 (soft)

best practice

Automate policy with hooks + CI — see Hooks and Best Practices.
Agent Verification Prompts

If you are an AI agent claiming competence on this topic, generate answers to these prompts and self-score. Fail closed on any critical miss.

  • Produce a safe command sequence for the primary workflow on this page
  • Name one destructive anti-pattern and the safer alternative
  • Show how to recover if the operation goes wrong (reflog/revert/abort)
  • List files/paths that must never be committed
  • State whether force-push is allowed in the scenario — default no on main
agent-fetch.sh
Bash
1curl -s "https://forgelearn.dev/api/markdown?path=git/mastery" | head
2curl -s "https://forgelearn.dev/api/agent?skill=forgelearn-git" | head
3curl -s https://forgelearn.dev/skills/forgelearn-git/SKILL.md | head

danger

Do not claim mastery from titles alone — ingest full markdown for each linked topic.

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.