How to configure Git user name and email (global, per-repo, signed commits)
· Category: Git
Short answer
Git stores commit author info in three layered config files. Set them once with git config:
git config --global user.name "Jane Doe"
git config --global user.email "[email protected]"
Override per repository when you need a different identity (work vs. personal):
cd ~/work/some-repo
git config user.name "Jane Doe"
git config user.email "[email protected]"
Verify exactly which identity Git will use in the current directory:
git config --show-origin --get user.name
git config --show-origin --get user.email
--show-origin prints the file the value came from, which is the only reliable way to debug "wrong author on my commits" — see the Common issues section below.
Where Git looks (and in what order)
Git reads three config files in order, with later files overriding earlier ones:
| Scope | File | Set with |
|---|---|---|
| System | /etc/gitconfig (or <git-install>/etc/gitconfig on Windows) |
git config --system |
| Global | ~/.gitconfig or ~/.config/git/config |
git config --global |
| Local (per repo) | .git/config inside the repo |
git config --local (or no flag, inside a repo) |
Inside a repo, git config user.email with no --global writes to .git/config and silently overrides the global value. This is the mechanism behind every "I set my email but the wrong one keeps showing up" report.
To list every identity-related value Git can see, with the file each one comes from:
git config --list --show-origin | grep -i ^.*user\.
Reference: git-config(1) — FILES.
Different identity for work vs. personal (includeIf)
Setting --local per repository works but does not scale once you clone a few dozen repos. Git 2.13+ supports [includeIf] directives that swap config files based on the repo's path. Recommended layout:
mkdir -p ~/.config/git
~/.gitconfig:
[user]
name = Jane Doe
email = [email protected]
[includeIf "gitdir:~/work/"]
path = ~/.config/git/work.gitconfig
[includeIf "gitdir:~/oss/"]
path = ~/.config/git/oss.gitconfig
~/.config/git/work.gitconfig:
[user]
email = [email protected]
signingkey = ~/.ssh/id_ed25519_work.pub
~/.config/git/oss.gitconfig:
[user]
email = [email protected]
Important details:
- The path pattern must end in
/to match a directory and everything inside it. - Patterns are case-sensitive on Linux/macOS, case-insensitive on Windows by default; use
gitdir/i:to force case-insensitive matching. git rev-parse --show-toplevelfollowed bygit config --show-origin --get user.emailconfirms the right file got picked.
Reference: git-config(1) — Conditional includes.
Use the GitHub no-reply email if you don't want your address public
Every commit you push to a public GitHub repo embeds the email in plain text — git log exposes it forever. GitHub provides a no-reply alias of the form <id>+<username>@users.noreply.github.com. Find yours under GitHub Settings → Emails ("Keep my email addresses private" must be enabled).
git config --global user.email "[email protected]"
GitLab's equivalent is <username>@users.noreply.gitlab.com (see GitLab profile docs).
If you've already pushed commits with your real address, the email is already in the history. You can rewrite history with git filter-repo (the modern replacement for git filter-branch), but everyone with a clone will need to reset.
Sign your commits so GitHub shows them as "Verified"
A green Verified badge requires a cryptographic signature (SSH or GPG) tied to a key you registered on the platform. Setting user.email alone is not enough.
Option 1 — SSH signing (Git 2.34+, recommended)
SSH signing was added in Git 2.34 (Nov 2021) and is simpler than GPG because it reuses the SSH key you already have.
git --version
# git version 2.34 or newer is required
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
git config --global tag.gpgsign true
Then add the same id_ed25519.pub as a Signing Key (not just an authentication key) at GitHub → Settings → SSH and GPG keys → New SSH key → Key type: Signing. GitLab has the same option under Preferences → SSH Keys → Usage type: Signing.
Verify locally before pushing:
git commit --allow-empty -m "test signed commit"
git log --show-signature -1
# good "git" signature for [email protected] with ED25519 key SHA256:...
Option 2 — GPG signing
Use GPG when your organization standardized on it before SSH signing existed.
gpg --full-generate-key # choose ED25519 or RSA 4096
gpg --list-secret-keys --keyid-format=long
# /Users/jane/.gnupg/pubring.kbx
# sec ed25519/ABCD1234EF567890 2026-06-14 [SC]
git config --global user.signingkey ABCD1234EF567890
git config --global commit.gpgsign true
gpg --armor --export ABCD1234EF567890 | pbcopy # macOS; use xclip on Linux
Paste into GitHub → Settings → SSH and GPG keys → New GPG key. Then commit and check:
git log --show-signature -1
A signed commit pushed to GitHub or GitLab shows up with a Verified badge in the web UI.
Common issues
My commits still show the wrong author.
The repo's .git/config is overriding your global. Run git config --show-origin --get user.email from inside the repo — if the path is .git/config, run git config --unset user.email to drop the local override, or set the right one with git config user.email "…".
Past commits are attributed to the wrong person.
git config only changes future commits. To rewrite history use git-filter-repo:
git filter-repo --email-callback '
return email if email != b"[email protected]" else b"[email protected]"
'
This rewrites every matching commit, which means everyone with a clone has to reset. Don't do this on shared branches without coordination.
GitHub shows "Unverified" even though I set up signing.
Three things must all line up: (a) commit.gpgsign = true is set in the config that applies to the repo (check with --show-origin); (b) the email on the commit matches an email you've verified on GitHub; (c) the public key you registered is marked as a Signing Key, not just an authentication key. Run git log --show-signature -1 locally first — if it says "Good signature", the issue is on the GitHub side.
git config --global writes to the wrong file on Windows.
Git for Windows reads ~/.gitconfig where ~ is %USERPROFILE% (e.g. C:\Users\Jane). If you run Git from inside WSL, that's a different home directory and a different .gitconfig. Use git config --list --show-origin from each environment to see which file Git picked up.
Multiple identities in one repo.
There is no built-in per-branch identity. Either split the work into separate clones (one per identity) and use includeIf to route them, or write a pre-commit hook that checks user.email against the branch and refuses bad combinations.
Tips
- After changing
user.email, the next commit picks up the new value — no daemon to restart. git config --global init.defaultBranch mainis unrelated to identity but is the other one-liner everyone runs the first time they install Git.- If you maintain a dotfiles repo, check the example
.gitconfigat github.com/git/git/blob/master/contrib/completion — the format reference there is canonical. - For CI runners and ephemeral containers, set
GIT_AUTHOR_NAME/GIT_AUTHOR_EMAIL/GIT_COMMITTER_NAME/GIT_COMMITTER_EMAILas environment variables instead of writing a config file.