Every commit git creates carries an author name and an author email, and both come from exactly two config values. To git configure username and email content for the first time, run git config --global user.name "Your Name" and git config --global user.email "you@example.com" — that's the entire setup for most people, and it's usually the "Please tell me who you are" error during your first git commit that sends you looking for it. This guide covers all three things people actually need from that config file: setting the identity at whatever scope makes sense, checking and listing what's currently in effect, and editing the file directly when a command isn't the right tool. It also covers the confusion this search invites — a fresh clone of a remote repository inherits your global identity automatically, so nothing here is required again after cloning, and "git config username and password" is a different topic entirely, covered head-on in its own section below.

Quick Answer: Set Your Git Identity in Two Commands

The two commands that cover the overwhelming majority of this search:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Those two lines are the whole of "git set username and email", "set git user name", and "git config set username and email" — three phrasings of one job. Everything past that is a variation on scope (global vs. just this repo), direction (setting vs. checking vs. editing), or a specific failure mode (wrong author, two accounts, a credential prompt mistaken for this). The table below routes each variant to its command; full explanations follow in the linked sections.

Situation Command Notes
Set identity for every repo on this machine git config --global user.name/user.email ... Writes to ~/.gitconfig
Set identity for one repo only git config user.name/user.email ... No --global — writes to .git/config, overrides the global value here only
Check the effective username git config user.name Prints the value after scope resolution — the answer to "git check username"
See every set value with its source file git config --list --show-origin The full "show git config" answer
Script-safe check, no extra output git config --get user.name Exits 1 if unset — safe in a conditional
Edit the config file directly git config --global --edit Opens core.editor on the raw file
Auto-switch identity by folder includeIf "gitdir:~/work/" No manual switching between work and personal repos
Fix the author on the last commit git commit --amend --reset-author --no-edit Full detail in the amend guide

For the official flag reference, see git's own git-config documentation.

What user.name and user.email Actually Do

user.name and user.email are two keys in a config file, nothing more exotic than that. When you run git commit, git reads whatever those keys currently resolve to and bakes them into the commit object as the author's name and email — permanently, as part of that commit's content. Nothing validates the value against anything: git doesn't check that the email is real, doesn't check it against any account, and doesn't ask you to confirm it. Whatever string is set becomes the recorded author, typos included.

This is worth separating clearly from authentication, because the two get conflated constantly. An SSH key or a personal access token is what lets you push to a remote — it proves to GitHub, GitLab, or Bitbucket that you're allowed to write to that repository. It has no connection whatsoever to what a commit says about who wrote it. You can push successfully with a perfectly valid SSH key while every commit in that push is attributed to the wrong person, because authorship and push authentication are read from two completely different places at two completely different times.

GitHub (and GitLab, and Bitbucket) link a pushed commit to a user profile by matching the commit's author email against every email address registered on an account — including secondary and noreply addresses. When the match succeeds, the commit shows that account's avatar and links to its profile. When it doesn't, the commit still displays, but as a plain text name with no avatar and no profile link — it exists, it pushed fine, it's just not credited to anyone. That single distinction — identity config drives authorship, credentials drive push access, and GitHub bridges the two only via email matching — explains nearly every "wrong author" confusion covered later in this guide.

Two separate paths — identity config vs. push authentication user.name user.email git commit bakes in author SSH key / PAT authenticates push git push accepted GitHub matches author email to a registered account Linked to profile avatar shown No match unlinked name GitHub's email match is the only place these two paths meet.
Identity config (user.name/user.email) and push authentication (SSH key or PAT) are read at completely different times. The two paths meet only when GitHub matches the commit's author email against the account's registered emails — the sole link between "who wrote it" and "who's allowed to push it."

One more real consequence of the setting being unset entirely: git refuses to create your first commit and stops with a message that spells out exactly what to run.

$ git commit -m "initial commit"

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'you@hostname.(none)')

That error is the moment most people first encounter this whole topic, which is also why "git config user email" and "git config user name" rank as separately searched phrases — people are frequently typing the exact two lines from that message back into a search box.

Set Your Identity: Global, Per-Repo, and Everything Between

Set username and email in git globally first — it's the one-time step that covers every repository you'll ever clone on that machine as that OS user:

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

That pair is exactly what "git set name and email" and "git set user name email" are asking for: two independent keys, one command each, run once. There is no combined key and no shorthand — git config email is not a thing, and "set user email git" resolves to the same user.email line as every other phrasing of it.

Git set username alone, without an email, still lets you commit — git only refuses when both are unset in some configurations, and warns rather than blocks in others depending on version and platform. Set both regardless; a name with no matching email is functionally useless for GitHub's account-matching described above.

To set user in git for one repository only — a client project that needs a different address than your default, for instance — run the identical command from inside that repository's directory, minus --global:

cd client-project
git config user.name "Your Name"
git config user.email "you@client-example.com"

This writes to .git/config instead of ~/.gitconfig, and it overrides the global value in this repository only — every other clone on the machine keeps using your default. This is the practical answer to "git set account": there's no separate account concept in git itself, just a name-and-email pair scoped to wherever you set it.

System and worktree scope, briefly

Two less common scopes exist. git config --system user.name ... writes to a machine-wide file that applies to every user account on that computer — it needs administrator or sudo privileges to edit, and is rarely the right place for a personal identity setting on a single-user development machine. git config --worktree user.email ... is scoped even narrower than local — one specific worktree in a repository that has more than one — but it only works after explicitly opting in with git config extensions.worktreeConfig true; without that, a --worktree write silently behaves like --local instead. Both are covered by name in the scopes table in the next section, since precedence between all four is the part that actually matters day to day.

Check Your Config: See, List, and Show What Git Is Using

Once an identity is set somewhere, the next question is almost always which git username and email are actually in effect right now — especially once more than one scope is in play. Four commands cover it, from a single effective value to everything at once.

1. git config user.name and git config user.email — the direct answer to "git check username," "git get username," "git see username," "git show username," and "git show user." Run with no flags, these print the single effective value after every scope has been resolved — worktree, then local, then global, then system, most specific value wins:

$ git config user.name
Your Name

$ git config user.email
you@example.com

2. git config --get user.name — functionally the same read, but the script-safe form: it prints exactly one line and returns exit code 1 with no output if the key is unset anywhere, so a shell script can branch on it directly instead of parsing an error string.

3. git config --list (or its short form git config -l — the two are identical) — this is see git config, git config list, and list git configuration answered in one command. It prints every key currently set across all scopes, merged, with no indication by default of which file each line came from:

$ git config --list
user.name=Your Name
user.email=you@example.com
core.editor=vim
credential.helper=osxkeychain
remote.origin.url=https://github.com/acme/app.git

4. git config --list --show-origin — the same full list, but each line is prefixed with the exact file it came from, tab-separated. This is the real fix for "show git config" and "git display config" once you have more than one scope in play and need to know which file actually won:

$ git config --list --show-origin
file:/Users/you/.gitconfig	user.name=Pavel Volkov
file:/Users/you/.gitconfig	user.email=you@example.com
file:.git/config	user.email=you@work-example.com

A close cousin, git config --list --show-scope, prints the scope name ( global, local, system, worktree) instead of the file path:

$ git config --list --show-scope
global	user.name=Pavel Volkov
local	user.email=you@work-example.com

A real quirk worth knowing on macOS with Apple's bundled git: the system-level config actually lives inside Xcode's command line tools, and --show-scope reports it as scope unknown rather than system — the path is real and readable, the label just doesn't match the other three scopes cleanly.

5. git config --show-origin user.email — narrows --show-origin to a single key, telling you exactly which file set the value git is currently using for that one setting, without listing everything else:

$ git config --show-origin user.email
file:/Users/you/.gitconfig	you@example.com

This single-key form pays off in exactly the situation that sends most people looking for it: a commit shows an unexpected author, and you need to know in ten seconds whether the wrong value is coming from global or from a stray local override — the diagnosis flow gets its own section below.

Reading a --show-origin conflict $ git config --list --show-origin file:~/.gitconfig user.email=you@example.com global file:.git/config user.email=you@work-example.com WINS Same key, two files — the more specific scope (local) is what git actually uses. worktree > local > global > system
git config --list --show-origin prints every set key with the exact file it came from. When the same key appears in two files — here user.email set in both ~/.gitconfig and .git/config — the more specific scope always wins; local overrides global regardless of which line appears first in the output.

One genuinely useful habit if you maintain more than one machine, or a work and a personal laptop with different defaults: run git config --list --show-origin on both, save each to a text file, and paste them side by side into a plain text-diff tool. The one line that differs is usually the entire explanation for "it works on my laptop but commits are wrong on the desktop" — a comparison covered in more general form in the git diff between two files guide.

The Four Config Scopes and Where Their Files Live

Every way to git configure username and email comes down to which of four files the value lands in. Git resolves configuration from all four, and when the same key is set in more than one, the most specific scope wins. In order from most specific to least:

worktree  >  local  >  global  >  system
Scope Flag File location When to use
System --system Linux: /etc/gitconfig
Windows: C:\Program Files\Git\etc\gitconfig
macOS (Apple git): /Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig
Machine-wide defaults for every user account — rarely the right place for a personal identity
Global --global macOS/Linux: ~/.gitconfig (or $XDG_CONFIG_HOME/git/config only if ~/.gitconfig doesn't exist yet)
Windows: C:\Users\<You>\.gitconfig
Your default identity across every repository as this OS user — set it once
Local --local (the default when no scope flag is given) .git/config inside the repository One repository needs a different identity than your global default
Worktree --worktree .git/config.worktree (requires extensions.worktreeConfig enabled first) Different worktrees of the same repository need different values — the narrowest, least common case

The file-path nuance worth calling out explicitly: git writes global config to ~/.gitconfig whenever that file already exists, and only writes to $XDG_CONFIG_HOME/git/config (typically ~/.config/git/config) when ~/.gitconfig is absent. If you've ever wondered why editing one file doesn't seem to change anything, confirming which of the two actually exists on disk — with git config --show-origin user.name — settles it immediately rather than guessing.

Four config scopes — most specific wins ▲ most specific — wins when set Worktree --worktree · .git/config.worktree Local --local · .git/config Global --global · ~/.gitconfig System --system · /etc/gitconfig ▼ least specific — applies to everyone, everywhere Same key set in more than one file? Git always uses the value from the highest scope here.
Git resolves configuration from four files; when the same key is set in more than one, the most specific scope wins — worktree first, then local, then global, then system last.

Which git config Command to Use When

Side by side, every set-vs-check command this guide covers, so picking one is a lookup instead of a guess — whether you searched it as "git config user name" or "git config user email," both land in the same rows:

Task Command Notes
Set name globally git config --global user.name "..." Writes ~/.gitconfig
Set email globally git config --global user.email "..." Writes ~/.gitconfig
Set name/email for one repo git config user.name/user.email "..." No --global — writes .git/config
Set both in one command git config --global user.name "N" && git config --global user.email "E" git config user alone is not a valid command, and neither is git config username email — it fails with key does not contain a section, because user.name and user.email are separate dotted keys
View effective name/email git config user.name / git config user.email Resolved value after scope precedence
View everything, unlabeled git config --list (or -l) Identical commands, merged across all scopes
View everything with source file git config --list --show-origin Best for diagnosing which scope won
View everything with scope name git config --list --show-scope Prints global/local/system/worktree
Script-safe single value git config --get user.name Exits 1 with no output if unset
Edit the file directly git config --global --edit (or -e) Opens core.editor
Remove a value git config --global --unset user.name Falls back to the next scope down, if any is set

The one-line rule: reach for git config user.name/user.email for a quick check, --list --show-origin the moment two scopes might be in conflict, and --get only when a script needs to branch on the result without extra parsing.

Editing the Git Config File Directly

Every scope's config file is a plain INI-style text file — nothing about it requires the git config command specifically. Edit git config file content directly with the built-in editor flag, or with any text editor at all:

# Opens ~/.gitconfig in core.editor (defaults to vi/vim if unset)
git config --global --edit

# Equivalent short flag
git config --global -e

# Or just open it as a plain file
cat ~/.gitconfig
nano ~/.gitconfig

A minimal global config file with an identity set looks like this — the exact block that git config --global user.name/user.email writes for you:

[user]
	name = <Your Name>
	email = you@example.com
[core]
	editor = vim
[credential]
	helper = osxkeychain

Editing the file by hand is entirely equivalent to running the command — git reads whatever is on disk at read time, regardless of which tool wrote it. The one thing a text editor won't do for you that the command line does automatically is create missing parent sections or validate syntax before saving; a stray unmatched bracket in [user] breaks every subsequent git config read in that scope until it's fixed, whereas the CLI simply can't produce malformed syntax in the first place.

This also happens to be the fastest way to audit a work-versus-personal setup: open both .gitconfig files as plain text — paste their contents into a free two-pane diff view — and any difference in the [user], [includeIf ...], or [credential] blocks is visible immediately, without decoding two separate --show-origin outputs by hand.

Why Your Commits Show the Wrong Author

This is the single most common reason people end up needing to configure git identity a second time, after already having done it once: a commit lands under the wrong git username or email despite pushing successfully, and the SSH key or token used to push had nothing to do with it.

As covered above, GitHub links a commit to a profile by matching the author email against every address registered on an account. The most common concrete causes, roughly in order of frequency:

  • Global identity set to the wrong account. A machine shared between a personal and a work identity, where the global default was never updated after switching contexts — the classic case a work laptop still carrying a personal email, or vice versa.
  • A stale local override in one specific repository. Someone (possibly a past version of you, or a cloned template repo's committed setup script) ran git config user.email without --global inside this one repo, and it silently overrides your correct global default every time you commit here.
  • The email is genuinely correct but unregistered on the account. The commit shows a plain-text name with no avatar — not wrong, just unlinked, because that exact email was never added to the GitHub account's verified email list.
  • Pair programming or a copied commit carried over someone else's --author value via a cherry-picked commit or a rebase, and nobody reset it afterward.

Diagnosing which one applies takes one command, run inside the repository where the wrong commit happened:

git config --show-origin user.email

If the file path it returns is .git/config, a local override is the culprit — remove it with git config --unset user.email to fall back to your global default. If the path is your global file and the value itself is simply wrong, fix it there with git config --global user.email "correct@example.com". Either way, fixing the config only prevents future commits from repeating the mistake — commits already made keep whatever author they were committed with until you rewrite them, which is covered in full further down.

Diagnosing a wrong-author commit: three causes, three fixes Commit shows wrong author git config --show-origin user.email separately: origin: .git/config local override origin: ~/.gitconfig value itself is wrong email is correct but not registered on the GitHub account git config --unset user.email falls back to global default git config --global user.email ... sets the correct value Add/verify email in GitHub settings One command narrows two causes instantly; the third is a separate GitHub-side check.
git config --show-origin user.email narrows two of the three causes immediately: a value from .git/config is a local override, a value from ~/.gitconfig that's simply wrong needs a global fix. The third cause — an email that's correct but never added to the GitHub account — doesn't show up in git config at all; it's a check on GitHub's own email settings page.

Two Accounts, One Machine: Automatic Identity Switching

The durable fix for "wrong account committed" isn't remembering to switch manually before every commit — it's includeIf, a global-config directive (available since git 2.13.0) that loads a second config file automatically based on where a repository lives or which remote it points at. Set it up once, and the correct identity applies itself.

Switching by directory: gitdir:

Keep personal projects under one folder and work projects under another, then point your global config at a second file scoped to the work folder:

# ~/.gitconfig — personal default, plus a conditional include for work
[user]
	name = <Your Name>
	email = you@example.com

[includeIf "gitdir:~/work/"]
	path = ~/.gitconfig-work
# ~/.gitconfig-work — only applied inside ~/work/
[user]
	email = you@work-example.com

Any repository cloned under ~/work/ now commits under the work email automatically, with zero per-repo setup and nothing to remember before committing. The single most common mistake with this pattern is the trailing slash: gitdir:~/work/ has git append ** automatically, matching every repository nested anywhere below that folder recursively — drop the trailing slash and the pattern behaves differently and can fail to match subdirectories the way you expect. gitdir/i: is the same condition case-insensitively, useful on case-insensitive filesystems like default macOS and Windows setups. One subtlety worth knowing: symlinks inside $GIT_DIR are matched as-is, without being resolved to their target path first, though since git 2.13.0 both the symlink form and the resolved (realpath) form are matched for paths outside $GIT_DIR.

onbranch: (available since git 2.23.0) is the same mechanism keyed on the currently checked-out branch name instead of the directory — useful for repositories where identity should differ by branch rather than by location, though this is a far less common need than directory-based switching.

includeIf: automatic identity by folder ~/.gitconfig [user] email = default includeIf gitdir:~/work/ ~/personal/ no gitdir: match uses default ~/.gitconfig ~/work/ matched by gitdir:~/work/ loads a second file ~/.gitconfig-work [user] email = you@work-... Trailing slash matters: gitdir:~/work/ — git appends ** automatically to match every repo nested anywhere below that folder
A gitdir: condition in the global config loads a second file automatically based on where a repository lives. Repos under ~/work/ pick up ~/.gitconfig-work and its overriding email; repos anywhere else, like ~/personal/, keep falling through to the default in ~/.gitconfig. The trailing slash on gitdir:~/work/ is what makes git append ** and match every nested repository.

Switching by remote URL: hasconfig:remote.*.url:

A genuinely different case: work and personal repositories aren't cleanly separated by folder, but they are always cloned from a different host or org. hasconfig: remote.*.url: (added in git 2.36.0) matches on the repository's configured remote URL instead of its location on disk:

# ~/.gitconfig
[includeIf "hasconfig:remote.*.url:git@github-work:*/**"]
	path = ~/.gitconfig-work

Any repository whose remote matches that glob gets the work identity, wherever it sits on disk — the differentiator competitors covering only gitdir: tend to miss entirely. One real constraint: a config file included via a hasconfig:remote.*.url: condition is not itself allowed to declare a remote URL — the matching has to be resolved from the including file's own remotes, not from something the conditional file adds.

"Git Config Username and Password": What That Search Really Wants

Worth addressing directly, because the phrasing is easy to conflate with everything above: git config username and password is not about user.name and user.email at all. It's about authentication — proving to a remote host that you're allowed to push — which is a completely separate config namespace (credential.*, not user.*) governed by an entirely different set of commands.

The short version of why "password" doesn't apply anymore: GitHub removed support for password authentication on git operations in August 2021. HTTPS pushes now need a personal access token in place of a password, or you switch the remote to SSH and authenticate with a key pair instead — no password field exists in either flow. Setting up that switch on an existing clone, including the credential fallout either direction causes, is covered in full in the git change remote URL guide.

What actually stores and reuses your credentials once you have a token or key is the credential helper, configured with its own key:

git config --global credential.helper <helper-name>
Helper Platform Storage
store Any Plaintext file, ~/.git-credentials — readable by anyone with file access
cache Any In-memory only, 15 minutes by default, cleared on reboot
osxkeychain macOS macOS Keychain — encrypted, OS-managed
manager Windows (default), also macOS/Linux Git Credential Manager — OS-native secure storage
libsecret Linux System keyring (GNOME Keyring, KWallet)

Check which one is active with git config --get credential.helper — a value here, or the lack of one, has zero bearing on user.name/user.email; the two settings live in different config sections and get read at different points in git's workflow (credentials at push/fetch time, identity at commit time). Fixing one never fixes the other.

Email Privacy: GitHub's noreply Address

Setting user.email to your real address means every commit you push carries it in plain text, visible to anyone who clones or browses the repository — including public repos, forks, and any downstream mirror. GitHub's alternative is a generated noreply address that still links commits to your profile without exposing a real inbox.

For accounts created after July 2017, the format is ID+USERNAME@users.noreply.github.com — the numeric ID and username are both visible on your own GitHub profile settings page. Set it exactly like any other email:

git config --global user.email "12345678+yourusername@users.noreply.github.com"

Two account-side settings make this stick going forward: "Keep my email addresses private" in GitHub's email settings prevents your real address from being exposed even if a tool tries to read it from your profile, and "Block command line pushes that expose my email" actually rejects a push at the server if the commit's author email is your real, non-noreply address — turning a privacy preference into an enforced rule rather than a suggestion. Full walkthrough, including enterprise and organization variations, in GitHub's own documentation on setting your commit email address.

Fixing the Author on Commits You Already Made

Fixing user.email only changes commits from this point forward. A commit object stores author and committer as two separate identities, each with its own name, email, and timestamp — git log shows only the author by default; git log --format= fuller reveals both fields side by side. Amending or rebasing a commit someone else authored makes you the committer while preserving their original author fields — which is precisely how a co-worker's authored commit can carry your name as committer after you rebase it onto your branch. Environment variables GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL and GIT_COMMITTER_NAME/GIT_COMMITTER_EMAIL override config files entirely if set, which is worth checking if a fixed user.email still somehow doesn't take effect in one specific shell session.

Anatomy of a commit: two separate identities commit 9f8e7d6 AUTHOR name: Jane Doe email: jane@example.com date: 2026-07-20 09:14 COMMITTER name: Pavel Volkov email: you@example.com date: 2026-07-28 14:02 git log shows only author by default (--format=fuller reveals both) Rebase/amend of someone else's commit updates only the committer fields
A commit stores author and committer as two separate identities, each with its own name, email, and timestamp. git log shows only the author by default; --format=fuller reveals both. Amending or rebasing someone else's commit updates just the committer fields — their original author fields survive untouched.

The last commit

git commit --amend --reset-author --no-edit

--reset-author drops whatever author was recorded and replaces it with your current user.name/user.email; --no-edit keeps the message unchanged. Full detail on every amend flag, including fixing just the message or a forgotten file, lives in the git commit amend guide.

A range of recent commits

git rebase HEAD~5 --exec 'git commit --amend --no-edit --reset-author'

This replays the last five commits one at a time, resetting the author on each after it's checked out — no manual pick/edit editing required for a blanket fix across a range.

Bulk rewriting across full history

git filter-repo --mailmap .mailmap
# or, for logic beyond a simple name/email swap:
git filter-repo --commit-callback '...'

git filter-repo is the modern tool for this; git filter-branch is deprecated, and git itself prints a warning recommending filter-repo instead when you run it. Either way, every commit downstream of the earliest rewritten one gets a new SHA — the same fundamental mechanism covered for a single commit in the amend guide's interactive rebase section. Pushing the result needs --force-with-lease and advance coordination with anyone who's already pulled the old history; if their local clone has drifted too far to reconcile cleanly, resetting hard onto the rewritten remote is usually the cleanest recovery, and the reflog covered there is the safety net if that reset goes further than intended.

Display-only fix: .mailmap

A genuinely under-covered option when a full history rewrite is overkill: a .mailmap file at the repository root remaps names and emails in git log and git shortlog output without touching a single commit hash. Old commits keep their original SHAs and their original recorded author exactly as committed — only what's displayed changes. This is the right tool when the goal is a clean-looking contributor list rather than a historically accurate rewrite, and it carries none of the force-push coordination risk that filter-repo does.

One scope check before any of this: if the actual goal is undoing a commit entirely — not reattributing it to the right author — that's a different job, covered end to end in the git undo last commit guide.

Troubleshooting Config That Won't Take Effect

A short list of the actual causes behind "I ran the commands to git configure username and email, and nothing changed."

A local value is silently overriding your global change. By far the most common cause. You ran git config --global user.email "new@example.com", but the repository you're testing in already has a local override from before — local always wins. Confirm with git config --show-origin user.email; if it points at .git/config, remove the override with git config --unset user.email to fall through to your (now-correct) global value.

error: could not lock config file /etc/gitconfig: Permission denied — you tried to write system scope without elevated privileges. Either re-run with sudo (Linux/macOS) or, more likely, you didn't actually mean system scope at all — drop --system for --global, which almost every personal identity setting should use instead.

git config --global --edit opens an editor you don't want, or nothing opens at all — check git config core.editor; an unset or broken editor path is the usual cause. Set it explicitly, e.g. git config --global core.editor "code --wait", and retry.

An includeIf block isn't applying. Almost always the trailing slash on a gitdir: pattern, or a path that doesn't actually match — remember git appends ** automatically only when the pattern ends in a slash. Confirm the resolved value from inside the affected repository with git config --show-origin user.email; if the origin file isn't the one you expect, the condition itself, not the included file's contents, is the problem.

Cloned a fresh repository and the identity looks wrong immediately. A brand new clone never carries a user.name/user.email of its own — .git/config starts with only the remote's URL and tracking info, so what you're seeing is always your existing global (or an includeIf-matched) value, never something baked into the repository by whoever pushed it. If that value is wrong, the fix is scope-level as described throughout this guide, not something specific to the clone operation.

Environment variables are overriding everything. GIT_AUTHOR_EMAIL or GIT_COMMITTER_EMAIL set in your shell profile or a CI job's environment beat every config file, at every scope, with no warning that they're doing so. Run env | grep GIT_ before assuming a config fix didn't work.

Frequently Asked Questions

How do I set my git username and email?

Run git config --global user.name "Your Name" and git config --global user.email "you@example.com" once per machine — this covers every repository you touch as that OS user. Drop --global inside a specific repository to override just that one, which is common when a work project needs a different email than your personal default. If you skip this step entirely, git refuses to create your first commit with a "Please tell me who you are" error that names these exact two commands, which is why most people land on this setup step reactively rather than proactively. Both values are stored as plain text in a config file, not validated against any account, so a typo only shows up later as a wrong author on a commit.

How do I check what username and email git is using?

git config user.name and git config user.email print the effective value after all scopes are resolved — the direct answer to "git check username" and "git get username." For everything at once, git config --list --show-origin lists every set key alongside the exact file it came from, which is the fastest way to confirm whether a value is coming from global or local scope. git config --get user.name is the script-safe form: it prints one line and exits 1 if unset, so a shell script can branch on it without parsing extra output. Nothing here touches the network — all of it reads local config files instantly.

What's the difference between global and local git config?

Global config lives in ~/.gitconfig (or $XDG_CONFIG_HOME/git/config when ~/.gitconfig doesn't exist yet) and applies to every repository that OS user touches, set with git config --global. Local config lives in .git/config inside one specific repository and applies only there, set with the same command minus --global. Local always wins over global when both set the same key, because git resolves scopes from most specific to least specific: worktree, then local, then global, then system. The practical use: set your usual identity once with --global, then override user.email locally in the one repository that needs a different address — a client project or a work monorepo, for instance.

Why do my commits show the wrong author on GitHub?

Commit authorship comes entirely from user.name and user.email at the moment you run git commit — nothing else. An SSH key or personal access token authenticates your push; it has zero influence on who a commit says wrote it, which is why a commit can push successfully under a completely wrong name. GitHub links a commit to an account by matching the author email against every email registered on that account; if the email doesn't match anything, the commit shows an unlinked plain-text name instead of a profile. Check git config --show-origin user.email in the repository to see which file set the wrong value, fix it, then fix already-made commits with git commit --amend --reset-author or an interactive rebase.

How do I use different git accounts for work and personal projects?

Use includeIf in your global ~/.gitconfig to load a second config file automatically based on the repository's location or its remote URL — no manual switching required. A gitdir: condition like [includeIf "gitdir:~/work/"] applies a separate file to every repository under that folder; the trailing slash matters, since git appends ** automatically and matches recursively. hasconfig:remote.*.url: (git 2.36.0+) switches based on the remote URL instead — useful when work and personal repositories are mixed in the same folder tree. Both conditions were added well after includeIf itself (git 2.13.0): onbranch: arrived in git 2.23.0, hasconfig:remote.*.url: in git 2.36.0.