mykhailoklym94
mykhailoklym94

Reputation: 588

How git resolves user.email and password to authenticate user?

I have global git configuration (~/.gitconfig) where my email is [email protected].

When I am in a local repository(I authenticated before with https) and I type git config user.email and my user name is still [email protected].

However, for this local repository, I am authenticated with a different email than the one that I have and which displays with config.

The question is, how git knows which email/user to use? I also checked the file in local repository .git/config -> and there is no information about email at all.

Upvotes: 2

Views: 548

Answers (2)

torek
torek

Reputation: 487993

It's worth noting that there is no authentication here. Git simply believes whatever claim you make. You can claim to be Barack Obama, or Angela Merkel, or whoever you like. Git will simply believe you.

The question is, how git knows which email/user to use?

Git performs the equivalent of:

git config --get user.name

to get the user name, and:

git config --get user.email

to get the email address to use. See also Doug Richardson's answer; consider using --list-origins to see all the places this particular git config might find a setting.

Internally, for the purpose of determining the output of git config --get user.name, what Git does is read the widest (--system) configuration first. If that sets a name, that is, for the moment, your name. Next, Git reads the --global configuration file. If that sets a name, it overrides any previous setting, and now that is your name—for now at least. Then Git reads the --local configuration file, typically .git/config. If that sets a name, it overrides any previous setting. If there is a per-work-tree configuration (and if your Git is new enough to have per-work-tree configurations), Git goes on to read that one, with the same sort of behavior. The git commit command does not supply a --file option to its internal git config --get, so that's the last place that can override your name—but see below.

If none of these have set a name, some versions of Git have a final fallback, where they query some system setting. This depends on your OS, and some settings that whoever built you Git binary chose at the time they built your Git binary.

The user name and email address here are recorded into commit objects. Once set in some particular commit object, that name and email address cannot be changed. If they are wrong, you can throw that commit away and replace it with a new-and-improved one, using git commit --amend, after changing the settings.

The git command itself has optional -c arguments:

git -c user.name=hello user.email=world@large commit ...

will, for the purpose of this one git commit command, set your name-and-email to hello <world@large>. You can also override the user name and/or email address setting with GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_COMMITTER_NAME, and GIT_COMMITTER_EMAIL environment variables. As in all the other cases, if you set these, Git just believes you, no matter how outrageous your claim may be.


Note that if you use ssh:// or https:// URLs for git push and git fetch, the ssh or http connection itself does not use these names. Here, Git relies on external programs and helpers. These external programs and helpers are OS-specific: Linux and Windows use different methods to figure out who you are, and when you connect from your machine to another server, the server will (probably) do some kind of authentication, to verify that you are who you claim to be, and that you should have access to the server.

This authentication, if and when it occurs, is mostly outside the scope of Git. There are a few Git helpers, some of which come with Git, that are useful on particular OSes. See, for instance, disable git credential-osxkeychain for information about tweaking the MacOS "osxkeychain" helper.

Upvotes: 2

Doug Richardson
Doug Richardson

Reputation: 10811

git config --list --show-origin

This command will show you all config options and also the location of each file that sets that option.

From the docs:

When reading, the values are read from the system, global and repository local configuration files by default, and options --system, --global, --local, --worktree and --file can be used to tell the command to read from only that location (see FILES).

...

ENVIRONMENT

GIT_CONFIG

Take the configuration from the given file instead of .git/config. Using the "--global" option forces this to ~/.gitconfig. Using the "--system" option forces this to $(prefix)/etc/gitconfig.

Upvotes: 3

Related Questions