Git merges configuration from, in increasing precedence: the hardcoded defaults, system config (/etc/gitconfig or the Homebrew prefix equivalent), global config (XDG config at ~/.config/git/config, then ~/.gitconfig, with ~/.gitconfig winning), the repository's .git/config, the per-worktree config when extensions.worktreeConfig is enabled, and finally '-c key=value' on the command line. For a single-valued key the last one read wins.
Debugging by opening files by hand is a waste of time. 'git config --list --show-origin --show-scope' prints every effective entry with its scope name and file path; --show-scope was added in Git 2.26 (March 2020). 'git config --show-origin --get user.email' answers the question for one key.
Beware that includeIf directives, commonly used to switch identities per directory, are expanded in place, so the reported origin is the included file, not ~/.gitconfig. The conditional gitdir patterns are case-sensitive and require a trailing slash to match a directory subtree.