Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hierarchical git config

Tags:

git

On my personal machine I have set my personal email address in my global git config.

$ git config --global --get user.email
[email protected]

However, I also have my company's code checked out, and as such, I need to configure git with my company's email address.

$ cd corp/project
$ git config --local --get user.email
[email protected]

Sometimes, however, when cloning a repo I forget to override my email address, and so I commit using my personal email address.

It would be possible to remove my global git config, thereby preventing me from committing in any repo before setting user.email in the local git config.

This is a bit of a pita though, and in an ideal world I would be able to set a hierarchical git config so that repos under a certain subdirectory (or some other means of working out which config applies) use the most specific setting therein.

Something like the following:

~/
|
+--- .gitconfig               # sets personal email address
|
+--- src/
     |
     +--- project/            # ~/.gitconfig email address applies 
     |    
     +--- corp/
          |
          +--- .git/config    # sets corp email address
          |
          +--- project/       # corp/.git/config email address applies

AFAIK currently this isn't natively possible with git, it would require a new level of config which sits between global and local

Is there a way for me to achieve what I'm looking for here?

like image 721
Steve Lorimer Avatar asked May 01 '17 04:05

Steve Lorimer


People also ask

What is git global config?

The git config command is a convenience function that is used to set Git configuration values on a global or local project level. These configuration levels correspond to . gitconfig text files. Executing git config will modify a configuration text file.

What are the three levels of configurations available in git?

# There are 3 levels of git config; project, global and system.

What is git config -- list?

The git config list command will show all Git config properties throughout all of the variously scoped Git files. If the value displayed is different from the value expected, then an override is happening in one of the other Git config scopes.


3 Answers

It is not supported yet, however as of git 2.8 (Mar '16) you can disable global user config as follows:

git config --global user.useConfigOnly true

That way git will never let you commit until you set an email in your local config. You can think of a script to fetch your global settings and copy to local config for a quick solution though.

like image 154
hurturk Avatar answered Nov 06 '22 21:11

hurturk


Checkout out this great post on git hooks by Orr Sella, specifically for e-mail use. He completely foregoes a global config, and uses a hook to prevent a clone with no config available:

EMAIL=$(git config user.email)
if [ -z "$EMAIL" ]; then
    # user.email is empty
    echo "ERROR: [pre-commit hook] Aborting commit because user.email is missing. Configure user.email for this repository by running: '$ git config user.email [email protected]'. Make sure not to configure globally and use the correct email."
    exit 1
else
    # user.email is not empty
    exit 0
fi

The way to use this is in the post. You could refine this to look for a local config in the repository root, check for e-mail (using grep even) and if it doesn't exists use the global. Something like

EMAIL = $(grep user.email $GIT_DIR/config)
if [[ $? ]]; then 
    EMAIL = $(git config user.email)
    exit 0
fi
EMAIL = $(EMAIL##*user.email* )

GIT_DIR is guaranteed to be the repository root when the hook runs.

like image 26
kabanus Avatar answered Nov 06 '22 22:11

kabanus


AFAIK git itself does not support more than per-repo and global identity.

I archived similar stuff by using a cd hook in zsh:

# ~/.zshrc
# call this function after cd-ing into a directory
__zsh-on-cd () {
if git ls-files &>/dev/null ; then
    if [[ "$PWD" =~ 'Company' ]]; then
        echo "setting git to use company identity"
        git config user.name "John Doe"
        git config user.email "[email protected]"
    else
        echo "setting git to use personal identity"
        git config user.name "johndoes"
        git config user.email "[email protected]"
    fi
fi
}

chpwd_functions=(${chpwd_functions[@]} "__zsh-on-cd")
like image 29
Jokester Avatar answered Nov 06 '22 22:11

Jokester