Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Git seems to support configuration values at three levels:

  • Per-system global settings (stored in /etc/git-core)
  • Per-user global settings (stored in ~/.gitconfig)
  • Per-repository local settings (stored in $REPO/.git/config)

These options cover most of the basis but I'm looking for a way to handle a fourth level. I have a (very) large collection of repositories for which I need to use a different value for user.email than my usual. These repositories are often created and manipulated through automated scripts, and setting up per repository local settings is cumbersome.

All of the repositories in question are located under a certain path prefix on my local system. Is there a way to set a configuration value somewhere that will be inherited by all repositories under that path? (Sort of like .htaccess settings inherit all the way up the file system.) Perhaps there would be a way to set conditional values in the global config file? What other arrangements could be made in a UNIX environment to cope with a set of repositories like mine?

share|improve this question
    
My first reflex is to hack the scripts to tweak .gitconfig in each directory they create. For example, IIRC Android's repo can do this, but you have to read the source carefully to find out. (I'm not completely sure, I haven't done that in a while.) – Gilles Jul 11 '12 at 22:37
    
@Gilles: That's certainly a possibility. The repos in question are the package repository for a Linux distro that has recently migrated from CVS to Git. We're still working on redoing all our tooling. In the long term that's probably where this gets fixed, but in the short term those of us working on it are experimenting with what the options are. – Caleb Jul 12 '12 at 9:04
up vote 10 down vote accepted

I have found no way to configure git at this fourth level. The only way seems to be per-command configuration value overrides using git -c key=value.

My current hacky solution is to define a shell function that serves as a wrapper for git. When called, it passes the arguments onto the system git command, but not before checking on the present working directory and adding an extra argument to the command if applicable.

function git () {
    case "$PWD" in
        /path/to/repos/*)
            command git -c user.email=alternate@credentials.org "$@"
            ;;
        *)
            command git "$@"
            ;;
    esac
}
share|improve this answer
    
can I do command git -c user.email=alternate@credentials.org user.name="Alter Ego" "$@" or how should I go about that? Searched high & low and the only reference to this -c flag I found was yours, thanks, much appreciated. – Vic Goldfeld Jan 28 '13 at 17:36
    
for the record, I got it working with command git -c user.email=alternate@credentials.org -c user.name="Alter Ego" "$@" – Vic Goldfeld Jan 28 '13 at 18:07

You can configure the email address for git with the environment variable GIT_AUTHOR_EMAIL. If you combine this with Execute bash scripts on entering a directory or directory specific shell configuration with zsh you can easily change the settings per directory or parent directory, e.g. if you enter into a directory in ~/work you can automatically adjust the environment variables to change your email address.

share|improve this answer

Based on Caleb's answer, we can define a modified git command which permanently configures all of the repositories in this directory correctly, so that all future uses of vanilla git will use the new configuration. I use hub, which is another git wrapper, so I replaced my alias git=hub with this and called hub in my function - if you don't use hub, replace all hub invocations with command git:

function git() {
    case "$PWD" in
        /home/robin/git/3RD_PARTY)
            hub "$@"
            # We don't know which repository was cloned / operated on, so let's just reconfigure them all
            for f in *; do
                [[ -d "$f" ]] && hub -C "$f" config user.email $my_private_email
            done
            ;;
        /home/robin/git/3RD_PARTY/*)
            hub "$@"
            hub config user.email $my_private_email
            ;;
        *)
            hub "$@"
            ;;
    esac
}

Unlike Caleb's answer, which only works in a shell (and unless explicitly sourced, only in an interactive shell), this also affects other git front-ends which correctly read the git config, such as emacs magit.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.