Use a different user.email and user.name for Git config based upon remote clone URL
I configure my global ~/.gitconfig
properties user.name
and user.email
like this:
git config --global user.email "[email protected]"
git config --global user.name "mkobit"
This is the default configuration I want for working on personal projects, open source stuff, etc.
When I am working on a project from a specific domain, a corporate domain for example, I am configuring it for each repository when I clone it so that it uses a different user.name
/user.email
:
git clone ssh://[email protected]:1234/groupA/projectA.git
cd projectA
git config user.email "[email protected]"
git config user.name "m.kobit"
One decent option would be to setup an alias for cloning these kinds of repositories:
git config --global alias.clonecorp 'clone \
-c user.name="m.kobit" -c user.email="[email protected]"'
git clonecorp ssh://[email protected]:1234/groupA/projectA.git
Both of these can be error prone because they both depend on me being smart and following the right steps. Evidence shows that this is near-guaranteed for me to screw-up sometime.
Is there a way to configure Git such that repositories from a certain domain (the mycorp.com
in this example) will be configured a certain way?
Solution 1:
The release of Git 2.13 has introduced a feature called conditional includes. In 2.13 the only supported configuration is filesystem path. That is easy to use in this case because I am already separating them.
The example provided on the release notes is:
You can configure two conditional includes in your home directory's
~/.gitconfig
file:[includeIf "gitdir:~/work/"] path = .gitconfig-work [includeIf "gitdir:~/play/"] path = .gitconfig-play
Now you can put whatever options you want into those files:
$ cat ~/.gitconfig-work [user] name = Serious Q. Programmer email = [email protected] $ cat ~/.gitconfig-play [user] name = Random J. Hacker email = [email protected]
Old answer
In Git 2.8, a global configuration user.useconfigonly
has been added that insists the user set their user.email
and user.name
are set before committing. Here is the relevant text from the linked blog post by Github:
But if, say, you want Git to use one email address for your open source projects and a different one for your work projects, you've undoubtedly made the mistake of committing to a new Git repository without having first set your email address in that repository. In this situation, Git emits a warning, but it creates the commit anyway, using an email address that it guesses from the local system hostname. If you're trying to do something as complicated as different addresses for different projects, this is almost certainly not what you want.
Now you can tell Git not to guess, but rather to insist that you set user.name and user.email explicitly before it will let you commit:
git config --global user.useconfigonly true
This doesn't solve the auto-config based on certain clone URLs, but does make the process a little bit less error prone by forcing configuration at the start.
Solution 2:
I found myself in the same situation: Realizing that i used my corporate email for commits just right after pushing to non-corporate repositories... So i wrote a small git-hook which you might find useful as well: https://github.com/DrVanScott/git-clone-init
Based on a configurable pattern file it will initialize user.email and user.name on git clone.
Solution 3:
When I am working on a project from a specific domain, a corporate domain for example, I am configuring it for each repository when I clone it
Make sure to use Git 2.22 (Q2 2019) if your condition include config IncludeIf
uses a pattern:
See commit 19e7fda (26 Mar 2019) by Nguyễn Thái Ngọc Duy (pclouds
).
(Merged by Junio C Hamano -- gitster
-- in commit 078b254, 22 Apr 2019)
config
: correct '**
' matching inincludeIf
patternsThe current
wildmatch()
call forincludeIf
's gitdir pattern does not pass theWM_PATHNAME
flag.
Without this flag, '*
' is treated almost the same as '**
' (because '*
' also matches slashes) with one exception:'
/**/
' can match a single slash.
The pattern 'foo/**/bar
' matches 'foo/bar
'.But '
/*/
', which is essentially what wildmatch engine sees withoutWM_PATHNAME
, has to match two slashes (and '*
' matches nothing).
Which means 'foo/*/bar
' cannot match 'foo/bar
'.
It can only match 'foo//bar
'.The result of this is the current
wildmatch()
call works most of the time until the user depends on '/**/
' matching no path component.
And also '*
' matches slashes while it should not, but people probably haven't noticed this yet. The fix is straightforward.