Skip to content

Instantly share code, notes, and snippets.

@ibqn
Created May 8, 2020 13:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ibqn/7ef5845c1a71e8f1a15c18c963c6979d to your computer and use it in GitHub Desktop.
Save ibqn/7ef5845c1a71e8f1a15c18c963c6979d to your computer and use it in GitHub Desktop.

This answer is partially inspired by the post by @Saucier, but I was looking for an automated way to set user.name and user.email on a per repo basis, based on the remote, that was a little more light weight than the git-passport package that he developed. Also h/t to @John for the useConfigOnly setting. Here is my solution:

.gitconfig changes:

[github]
    name = <github username>
    email = <github email>
[gitlab]
    name = <gitlab username>
    email = <gitlab email>
[init]
    templatedir = ~/.git-templates
[user]
    useConfigOnly = true

post-checkout hook which should be saved to the following path: ~/.git-templates/hooks/post-checkout:

#!/usr/bin/env bash

# make regex matching below case insensitive
shopt -s nocasematch

# values in the services array should have a corresponding section in
# .gitconfig where the 'name' and 'email' for that service are specified
remote_url="$( git config --get --local remote.origin.url )"
services=(
    'github'
    'gitlab'
)

set_local_user_config() {
    local service="${1}"
    local config="${2}"
    local service_config="$( git config --get ${service}.${config} )"
    local local_config="$( git config --get --local user.${config} )"

    if [[ "${local_config}" != "${service_config}" ]]; then
        git config --local "user.${config}" "${service_config}"
        echo "repo 'user.${config}' has been set to '${service_config}'"
    fi
}

# if remote_url doesn't contain the any of the values in the services
# array the user name and email will remain unset and the
# user.useConfigOnly = true setting in .gitconfig will prompt for those
# credentials and prevent commits until they are defined
for s in "${services[@]}"; do
    if [[ "${remote_url}" =~ "${s}" ]]; then
        set_local_user_config "${s}" 'name'
        set_local_user_config "${s}" 'email'
        break
    fi
done

I use different credentials for github and gitlab, but those references in the code above could be replaced or augmented with any service that you use. In order to have the post-checkout hook automatically set the user name and email locally for a repo after a checkout make sure the service name appears in the remote url, add it to the services array in the post-checkout script and create a section for it in your .gitconfig that contains your user name and email for that service.

If none of the service names appear in the remote url or the repo doesn't have a remote the user name and email will not be set locally. In these cases the user.useConfigOnly setting will be in play which will not allow you to make commits until the user name and email are set at the repo level, and will prompt the user to configure that information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment