25

I have separate email addresses that I use for work projects vs open source projects, and I want to ensure that I use the correct one for each type of project.

Obviously the solution is to set the repository specific configuration appropriately, unfortunately I keep forgetting to set it until I'm a few commits in and so am using the global user.email config, which is fine if that matches up with what I'm working on, but not so fine otherwise.

If the user.email isn't set anywhere git just crams the local username and host together to make one up (not so awesome for a desktop machine); I'd like it to just block the commit. I don't think hooks will work, since I want this to happen for new & cloned repos - if I'm manually copying a hook into a repo, I should probably set the config instead.

Cebjyre
  • 6,552
  • 3
  • 32
  • 57
  • Tangentially also https://gist.github.com/tripleee/16767aa4137706fd896c – tripleee Jun 09 '14 at 12:33
  • Note: with git 2.8+, the right solution will be `git config --global user.useConfigOnly true`. See [my updated answer below](http://stackoverflow.com/a/12292895/6309) – VonC Feb 18 '16 at 11:59

2 Answers2

29

New Update (February 2016, for git 2.8)

git 2.8 (March 2016) will add a new solution:

See commit 4d5c295 (06 Feb 2016) by Dan Aloni (da-x).
Helped-by: Eric Sunshine (sunshineco).
See commit 59f9295 (04 Feb 2016) by Jeff King (peff).
Helped-by: Eric Sunshine (sunshineco).
(Merged by Junio C Hamano -- gitster -- in commit c37f9a1, 17 Feb 2016)

ident: add user.useConfigOnly boolean for when ident shouldn't be guessed

It used to be that:

git config --global user.email "(none)"

was a viable way for people to force themselves to set user.email in each repository.
This was helpful for people with more than one email address, targeting different email addresses for different clones, as it barred git from creating a commit unless the user.email config was set in the per-repo config to the correct email address.

A recent change, 19ce497 (ident: keep a flag for bogus default_email, 2015-12-10 for git 2.6.5, Jan. 2016), however, declared that an explicitly configured user.email is not bogus, no matter what its value is, so this hack no longer works.

Provide the same functionality by adding a new configuration variable user.useConfigOnly; when this variable is set, the user must explicitly set user.email configuration.

So starting March 2016 and git 2.8, do:

git config --global user.useConfigOnly true

Any of your new repo will look for user.email only in their local .git/config file.
And the commit will not proceed if no user.email is found in the local git config.


Note that it will be enhanced some more in git 2.9 (June 2016):

See commit d3c06c1, commit 734c778 (30 Mar 2016) by Marios Titas (``).
(Merged by Junio C Hamano -- gitster -- in commit e7e6826, 29 Apr 2016)

ident: check for useConfigOnly before auto-detection of name/email

If user.useConfigOnly is set, it does not make sense to try to auto-detect the name and/or the email.
The auto-detection may even result in a bogus name and trigger an error message.

ident: give "please tell me" message upon useConfigOnly error

use a less descriptive error message to discourage users from disabling user.useConfigOnly configuration variable to work around this error condition. We want to encourage them to set user.name or user.email instead.

So instead of:

user.useConfigOnly set but no name given
user.useConfigOnly set but no mail given

You will see:

no name was given and auto-detection is disabled
no email was given and auto-detection is disabled

Original answer (Sept. 2012)

A bit like in "Stop a git commit by a specific author using pre-commit hook", you could define a default pre-commit hook which check if:

 git config --local user.email

is empty or not.
If it is empty: exit 1

To make sure you are using that default hook for every repo you are creating, see "change default git hooks".
It is a similar approach that the one described in "Share your git hooks":

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    Annoyingly, the hook template directory gets stomped on git upgrade (at least with homebrew), but a great solution nonetheless. – Cebjyre Sep 06 '12 at 05:20
  • @Cebjyre suggestion: if you replace the template directory installed by homebrew by a symlink to a custom template directory in your homedir, the next upgrade would involve restoring only that symlink. – VonC Sep 06 '12 at 05:37
2

There is a hack/workaround I've just discovered, just set default global e-mail to (none), like this:

git config --global user.email "(none)"

Little explanation: this workaround depends upon current email validation in the official git client source code so use it on your own risk.

Sergey Stolyarov
  • 2,587
  • 3
  • 27
  • 40
  • +1. It is used in this gist as well: https://gist.github.com/sebastianha/8742361f107efe0ac14f – VonC Nov 06 '14 at 21:06
  • 2
    This used to work well for me, but as of git 2.7.0 it appears to just use `(none)` verbatim instead of causing an error. – Bradd Szonye Feb 02 '16 at 19:59
  • 1
    Yep, it was broken by [this commit](https://github.com/git/git/commit/19ce497cf594a3c01af33a65b27b19e7459212d6), and right now someone is trying to add this as a new feature: http://www.spinics.net/lists/git/msg267031.html. – Sergey Stolyarov Feb 03 '16 at 04:58
  • @BraddSzonye I have updated [my answer above](http://stackoverflow.com/a/12292895/6309) to reflect the new 2.8 setting: `git config --global user.useConfigOnly true` – VonC Feb 18 '16 at 12:00