What Is Git Config? Set Up Git Like a Pro

Summarize this article with:
Every Git installation starts with a single command most developers rush through and never revisit. That command is git config, and it controls far more than just your name and email.
Understanding what is git config means understanding how Git decides which editor to open, how it handles line endings across operating systems, which credentials to use when pushing code, and how merge behavior works across your repositories.
This guide covers config levels and priority, how to set and read values, common settings that actually matter, aliases, conditional includes, platform-specific options, and troubleshooting the config problems that waste hours when left unchecked.
What is Git Config

Git config is Git’s built-in command for reading and writing configuration variables that control how Git behaves and looks. It handles identity settings, editor preferences, default branch names, merge strategies, and dozens of other options that shape your daily workflow.
Every time you run git commit, Git pulls your name and email from these config values. Every time you resolve a conflict, Git checks which merge tool you’ve told it to use. That’s git config doing its job behind the scenes.
The configuration itself is stored as plain-text key-value pairs in specific files on your system. The format looks like an INI file, with sections in brackets and keys listed below them. Nothing fancy, nothing binary.
According to Stack Overflow’s developer survey, 93% of developers use Git as their primary version control system. And yet, a surprising number of those developers barely touch their config beyond the initial user.name and user.email setup.
The command syntax follows a straightforward pattern: git config [scope] key value. You set things. You read things. You unset things. That’s basically it.
But git config is more than a one-time setup step. It’s the foundation that ties together how Git operates across your entire machine, across specific projects, and even across specific directories based on conditional rules. Took me a while to realize how much time proper config saves compared to fighting default behaviors every day.
Git Config Levels and Their Priority

Git reads configuration from multiple files, and they stack on top of each other in a specific order. The closer a config file is to the actual repository, the higher its priority.
There are three main levels (four if you count the worktree scope).
| Level | Flag | Scope | File Location |
|---|---|---|---|
| System | –system | All users on the machine | /etc/gitconfig |
| Global | –global | Single user, all repos | ~/.gitconfig |
| Local | –local | Single repository | .git/config |
| Worktree | –worktree | Single worktree | .git/config.worktree |
Priority flows upward. Local overrides global. Global overrides system. If the same key exists at multiple levels, the most specific one wins.
This layered approach exists for practical reasons. You want your name and email set globally so every repository picks it up. But you might need a different email for work repos versus personal projects. Local config handles that.
The worktree level showed up in Git 2.20 and honestly, most developers never touch it. It’s only useful if you’re running multiple worktrees from the same repository, which is a fairly niche setup.
Where Each Config File Lives on Different Operating Systems
This part trips people up more than it should. The file paths shift depending on your OS.
macOS and Linux: System config sits at /etc/gitconfig. Global config goes to ~/.gitconfig or ~/.config/git/config. Local config is always .git/config inside the repo.
Windows: System config lives in Git’s install directory (usually C:Program FilesGitetcgitconfig). Global config lands at C:UsersYourName.gitconfig. If you’re using Git Bash, the paths behave like Linux. Native Windows Git uses Windows-style paths.
When you can’t figure out where a value is coming from, run git config --list --show-origin. It prints every active setting alongside the file it came from. Saves you from digging through files manually.
How to Set Git Config Values

Setting a config value is one line. The syntax is git config [--level] key value.
The two commands you’ll run first after installing Git on any machine:
“ git config --global user.name "Your Name" git config --global user.email "your@email.com" `
That’s it. Those values now apply to every repository on your system unless a local config overrides them.
Scope flags matter. Without any flag, git config defaults to –local, writing only to the current repo's .git/config. Add –global for user-wide settings. Add –system for machine-wide settings (requires admin access on most systems).
To remove a value, use git config –unset key. For keys that hold multiple values, –unset-all clears everything.
Some keys accept multiple values. The –add flag appends a new value without replacing the existing one. You'll encounter this with things like remote URLs or custom merge drivers, but not with everyday settings.
GitHub now hosts over 180 million developers according to its 2025 Octoverse report, and every single one of them had to run git config at least once to set their identity before their first commit.
How to Read and List Git Config Values

Checking what’s configured is half the troubleshooting battle. And honestly, it should be the first thing you do when something feels off.
List everything:
` git config --list `
This dumps every active config value from all levels, merged together. The problem? You can’t tell which file each value came from.
List with source files:
` git config --list --show-origin `
Now you see something like file:/home/user/.gitconfig user.name=Your Name. Each value gets tagged with its source file. Extremely useful when a setting isn't behaving the way you expect.
List with scope labels:
` git config --list --show-scope `
This tags each value with “system,” “global,” or “local” instead of the file path. Cleaner output when you just need to know which level is responsible.
Query a single value:
` git config user.email `
Returns whatever Git would actually use for that key, considering all priority rules. Quick and direct.
For pattern matching across multiple keys, git config –get-regexp accepts a regex. Running git config –get-regexp alias shows all your defined aliases at once, which is handy when you've built up a collection over the years.
Common Git Config Settings

Most developers set user.name and user.email, then forget git config exists. But there are settings that make a real difference in how Git behaves day to day.
core.editor controls which text editor opens for commit messages, interactive rebase, and other multi-line inputs. Without this, Git falls back to whatever $EDITOR or $VISUAL is set to in your shell (often Vim, which catches beginners off guard).
init.defaultBranch sets the name for new repository branches. Since 2020, most teams switched from “master” to “main.” Setting git config –global init.defaultBranch main handles this automatically for every new repo you create with git init.
core.autocrlf manages line ending conversion between Windows (CRLF) and Unix (LF) systems. Set it to true on Windows, input on macOS/Linux. Get this wrong and you'll see phantom diffs on every file, which is annoying beyond belief.
pull.rebase tells Git to rebase instead of merge when pulling. Many teams prefer pull.rebase=true to keep a cleaner commit history without merge commits cluttering up git log.
credential.helper stores or caches your authentication credentials. On macOS, it uses Keychain. Windows uses Credential Manager. Linux typically uses libsecret or a cache with a timeout. Without this, Git prompts for your password on every push and pull. Your mileage may vary with SSH versus HTTPS setups.
The 2025 Stack Overflow Developer Survey confirms that Visual Studio Code holds 75.9% IDE market share among developers, making it the most common editor people configure in their git config.
Setting a Default Text Editor
This setting causes more confusion than it should, especially with VS Code.
VS Code: git config –global core.editor “code –wait”
The –wait flag is critical. Without it, Git thinks you've finished editing instantly because VS Code opens as a separate process and returns control to the terminal. The –wait flag tells the terminal to hold until you close the editor tab.
Sublime Text: git config –global core.editor “subl -n -w”
Vim: git config –global core.editor “vim”
Nano: git config –global core.editor “nano”
If no editor is configured and no $EDITOR variable is set, Git defaults to Vim on most systems. That "how do I exit Vim" search has been one of the top Stack Overflow questions for years. Set your editor explicitly and save yourself the headache.
Git Config and Aliases
Aliases let you create shortcuts for Git commands you type all the time. They live in your config file under the [alias] section.
The syntax is simple:
` git config --global alias.co checkout git config --global alias.br branch git config --global alias.st status `
Now git co does what git checkout does. git st runs git status. Small thing, but when you're running these commands dozens of times a day, it adds up.
Formatted log alias: This one’s popular among developers who want a readable commit history.
` git config --global alias.lg "log --oneline --graph --all --decorate" `
Running git lg now shows a compact, visual branch graph. Way better than the default log output.
Shell command aliases: Prefix with ! to run arbitrary shell commands through Git.
` git config --global alias.cleanup "!git branch --merged | grep -v main | xargs git branch -d" `
That alias deletes all local branches that have already been merged into main. I use something like this after every sprint cleanup.
Aliases get stored in the same config files as everything else. If you run git config –global –edit, you'll see them all under the [alias] section. Easy to read, easy to share across machines.
For teams working across software development projects, sharing a common set of aliases through technical documentation can reduce onboarding friction significantly. New developers don’t have to figure out which shortcuts the rest of the team is using.
Editing the Git Config File Directly

You don’t have to set every value through the command line. Sometimes opening the file and editing it by hand is just faster.
` git config --global --edit `
That opens your global config in whatever editor you’ve set with core.editor. If you haven't set one, it defaults to Vim on most systems.
The file uses an INI-like format. Sections sit in brackets, and keys go underneath them as simple key-value pairs.
` [user] name = Your Name email = your@email.com [core] editor = code --wait [alias] st = status co = checkout `
When manual editing beats the CLI: If you need to change five or six settings at once, or want to reorganize your aliases, opening the file directly is way more efficient than running individual commands.
One thing to watch for: syntax errors. A missing bracket or an extra space in the wrong place can break the entire config file. Git won’t load a malformed config and will throw an error on every command you try to run after that.
The fix is usually obvious once you look at the file. But if you’re editing the system-level config (which requires admin access), a bad edit can affect every user on the machine. Keep a backup before making changes there.
Teams using source control management for shared projects sometimes maintain a recommended config snippet in their project README, so new developers can paste it directly into their files.
Conditional Includes in Git Config

Conditional includes solve the most common git config annoyance: needing different settings for different projects on the same machine.
The classic case. You use your personal email for open source projects and your work email for company repos. Without conditional includes, you’d have to set local config in every single repository. Forget once, and your personal email shows up in your company’s commit history.
The includeIf directive loads a separate config file based on conditions like directory paths. It was introduced in Git 2.13.
` [user] name = Your Name email = personal@email.com
[includeIf “gitdir:~/work/”] path = ~/.gitconfig-work `
Then in ~/.gitconfig-work:
` [user] email = you@company.com `
Every repository inside ~/work/ automatically picks up your work email. Everything else uses your personal email. No manual steps.
The trailing slash matters. Writing gitdir:~/work/ matches all subdirectories. Without the slash, it only matches that exact path. This is the single biggest gotcha with conditional includes, and it trips up pretty much everyone the first time.
Edward Thomson (former GitHub engineer) documented how he uses conditional includes to separate his Microsoft work identity from his open source projects. His setup uses two separate includeIf blocks pointing to different config files based on which directory his repos live in.
Git 2.36 added hasconfig:remote..url conditions, letting you match based on a remote URL instead of a local directory path. Useful when you clone repositories into unpredictable locations but still want identity switching based on where the remote is hosted.
| Condition Type | Matches On | Min Git Version |
|---|---|---|
| gitdir: | Local directory path | 2.13 |
| gitdir/i: | Case-insensitive directory | 2.13 |
| onbranch: | Current branch name | 2.23 |
| hasconfig:remote.*.url: | Remote URL pattern | 2.36 |
One warning from a popular GitHub gist on this topic: any misconfiguration in your includeIf setup can cause the entire git config to fail silently. You won't get an error message. Git just quietly ignores the broken include and uses default values.
Git Config for Specific Platforms and Tools
Cross-platform teams hit config friction constantly. Windows, macOS, and Linux handle certain things differently, and git config is where you smooth those differences out.
Line Ending Configuration
This is probably the most frustrating cross-platform issue in all of Git. Windows uses CRLF line endings. Linux and macOS use LF. When developers on mixed platforms touch the same files, you get phantom diffs showing every line as changed even though the actual content is identical.
The fix lives in git config:
- Windows: git config –global core.autocrlf true
- macOS/Linux: git config –global core.autocrlf input
The true setting converts LF to CRLF on checkout and back to LF on commit. The input setting only converts CRLF to LF on commit, leaving checkout alone.
A better long-term solution is adding a .gitattributes file to the repo itself. That way, line ending rules travel with the project and don't depend on every developer configuring their local machine correctly. GitHub's own documentation recommends this approach over relying on individual core.autocrlf settings.
Credential Helpers Across Operating Systems
Each platform handles credential storage differently, and the config setting reflects that.
| Platform | Credential Helper | Config Command |
|---|---|---|
| macOS | Keychain | git config –global credential.helper osxkeychain |
| Windows | Credential Manager | git config –global credential.helper manager |
| Linux | libsecret or cache | git config –global credential.helper libsecret |
Without a credential helper, Git asks for your password on every push and pull when using HTTPS remotes. Configuring SSH keys is the other option, and many developers prefer it because it avoids the credential helper question entirely.
Configuring Diff and Merge Tools
Popular diff/merge tools like Beyond Compare, Meld, and KDiff3 integrate with Git through config settings.
` git config --global merge.tool meld git config --global diff.tool meld `
After that, running git difftool or git mergetool opens your chosen application instead of dumping everything into the terminal. Teams working on complex codebases with frequent merge conflicts find this saves real time.
Troubleshooting Git Config Issues

Config problems are some of the most common Git headaches. They’re also some of the easiest to fix, once you know where to look.
Commits Showing the Wrong Author Name or Email
This is the number one config-related complaint. You push a bunch of commits to GitHub, and they show up under the wrong user. Or worse, as an unrecognized author with no profile link.
The cause is almost always a mismatch between the email in your git config and the email associated with your GitHub account. Git doesn’t know anything about GitHub usernames. It just stores whatever email is in your config at commit time.
To check your current config:
` git config user.email git config user.name `
If the email doesn’t match what’s on your GitHub profile, that’s the problem. Fix it, and future commits will be attributed correctly. For existing commits, you’ll need to rewrite history with interactive rebase, which gets tricky on shared branches.
Editor Not Opening or Opening the Wrong One
According to the 2025 Stack Overflow Developer Survey, 75.9% of developers use Visual Studio Code. But if core.editor isn't set or points to the wrong binary, Git falls back to Vim.
Common causes:
- Missing –wait
flag for VS Code or Sublime Text
- Editor binary not in your system PATH
- core.editor
set at the wrong scope level
Run git config –show-origin core.editor to see exactly where your current editor setting comes from and what it's set to.
Config Values Not Taking Effect
You set a value at the global level, but Git keeps using something different. Scope priority is usually the culprit.
Diagnosis steps:
` git config --list --show-origin --show-scope `
Look for duplicate keys. If the same key appears at both global and local levels, the local value wins. That’s by design, but it surprises people who don’t realize a local config override exists in their repo.
Another subtle issue: the GITCONFIGCOUNT, GITCONFIGKEY, and GITCONFIGVALUE environment variables can inject config values at runtime. These override everything in your config files. If a build pipeline or CI script sets them, your local config won't matter.
Stack Overflow’s 2024 survey found that nearly 34% of revision-loss errors involved developers working in unexpected states, many of which trace back to config mismatches between what they expected and what Git was actually using.
Resetting a Config Value to Default
To remove a custom setting and let Git fall back to its default behavior:
` git config --global --unset core.editor `
That deletes the key entirely from the specified config file. The –unset flag only removes one value at a time. For keys that somehow ended up with multiple values (rare, but it happens), use –unset-all.
If you want to start fresh on global settings entirely, you can delete the ~/.gitconfig file. Git will recreate it the next time you set a value. Just make sure you've saved anything you want to keep first. Developers who adopt configuration management practices for their dotfiles (storing them in a Git repo, naturally) avoid losing their setup across machines.
FAQ on What Is Git Config
What does git config actually do?
Git config reads and writes configuration variables that control how Git operates. It sets your identity, default editor, merge behavior, and dozens of other preferences stored as key-value pairs in plain text files on your system.
Where is the git config file located?
It depends on the scope. The global config lives at ~/.gitconfig on macOS and Linux, or C:UsersYourName.gitconfig on Windows. Local config sits inside each repository at .git/config.
What is the difference between global and local git config?
Global config applies to every repository for your user account. Local config applies only to a single repository and overrides global values. Use local when a project needs different settings, like a separate work email.
How do I set my username and email in git config?
Run git config –global user.name “Your Name” and git config –global user.email “you@email.com”. These values appear in every commit you make and link your work to your identity on platforms like GitHub.
How do I see all my current git config settings?
Run git config –list to see every active setting. Add –show-origin to see which file each value comes from, or –show-scope to see whether it's system, global, or local level.
Can I use different git config settings for different projects?
Yes. Set values at the local level with git config –local inside each repo. Or use conditional includes with includeIf to automatically switch config based on directory paths, which is cleaner for managing multiple identities.
How do I change the default text editor in git config?
Run git config –global core.editor “code –wait” for VS Code. The –wait flag is required so Git knows to wait until you close the editor tab before proceeding with the commit or rebase.
What is core.autocrlf in git config?
It controls line ending conversion between Windows (CRLF) and Unix (LF) systems. Set it to true on Windows and input on macOS or Linux. Wrong settings cause phantom diffs where every line appears changed.
How do I create aliases in git config?
Run git config –global alias.st status to create a shortcut. Now git st runs git status. Aliases save keystrokes on commands you use constantly and get stored in the [alias] section of your config file.
How do I reset or remove a git config value?
Use git config –global –unset key.name to remove a specific setting. Git reverts to its default behavior for that key. For keys with multiple values, use –unset-all to clear everything at once.
Conclusion
Knowing what is git config gives you direct control over how Git behaves on your machine, inside your repositories, and across your entire software development process. It’s not a one-time setup task. It’s something you refine as your workflow changes.
The layered priority system (system, global, local) keeps things flexible. Conditional includes handle the work-versus-personal identity problem cleanly. Aliases cut repetition out of your daily command line routine.
Cross-platform settings like core.autocrlf and credential helpers prevent the kind of friction that slows down teams working across Windows, macOS, and Linux.
Most config issues come down to scope conflicts or forgotten overrides. Running git config –list –show-origin` is the fastest way to trace any problem back to its source file.
Spend ten minutes setting up your config properly. It saves hours down the line, whether you’re working solo or collaborating through a structured Git workflow with a full DevOps pipeline behind it.
- Android App Drawer vs Home Screen: Differences Explained - April 16, 2026
- 7 Things to Know Before Buying Refurbished Servers in 2026 - April 16, 2026
- iPhone Parental Controls: Complete Guide - April 15, 2026







