In my ~/.gitconfig
, I list my personal email address under [user]
, since that\'s what I want to use for Github repos.
But, I\'ve recently s
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.
I made a bash function that handle that. Here is the Github repo.
For record:
# Look for closest .gitconfig file in parent directories
# This file will be used as main .gitconfig file.
function __recursive_gitconfig_git {
gitconfig_file=$(__recursive_gitconfig_closest)
if [ "$gitconfig_file" != '' ]; then
home="$(dirname $gitconfig_file)/"
HOME=$home /usr/bin/git "$@"
else
/usr/bin/git "$@"
fi
}
# Look for closest .gitconfig file in parents directories
function __recursive_gitconfig_closest {
slashes=${PWD//[^\/]/}
directory="$PWD"
for (( n=${#slashes}; n>0; --n ))
do
test -e "$directory/.gitconfig" && echo "$directory/.gitconfig" && return
directory="$directory/.."
done
}
alias git='__recursive_gitconfig_git'
Maybe it is a simple hack, but it is useful. Just generate 2 ssh keys like below.
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/GowthamSai/.ssh/id_rsa): work
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in damsn.
Your public key has been saved in damsn.pub.
The key fingerprint is:
SHA256:CrsKDJWVVek5GTCqmq8/8RnwvAo1G6UOmQFbzddcoAY GowthamSai@Gowtham-MacBook-Air.local
The key's randomart image is:
+---[RSA 4096]----+
|. .oEo+=o+. |
|.o o+o.o= |
|o o o.o. + |
| =.+ . = |
|= *+. S. |
|o*.++o . |
|=.oo.+. |
| +. +. |
|.o=+. |
+----[SHA256]-----+
Same way create one more for personal. So, you have 2 ssh keys, work and company. Copy work.pub, work, personal.pub, personal to ~/.ssh/ Directory.
Then create a shell script with the following lines and name it as crev.sh (Company Reverse) with the following content.
cp ~/.ssh/work ~/.ssh/id_rsa
cp ~/.ssh/work.pub ~/.ssh/id_rsa.pub
Same way, create one more called prev.sh (Personal Reverse) with the following content.
cp ~/.ssh/personal ~/.ssh/id_rsa
cp ~/.ssh/personal.pub ~/.ssh/id_rsa.pub
in ~/.bashrc add aliases for those scripts like below
alias crev="sh ~/.ssh/crev.sh"
alias prev="sh ~/.ssh/prev.sh"
source ~/.bashrc
Whenever you wanna use company, just do crev, and if you wanna use personal do prev :-p.
Add those ssh keys to your GitHub accounts. Make sure, you don't have id_rsa generated previously, because those scripts will overwrite id_rsa. If you have already generated id_rsa, use that for one of the accounts. Copy them as personal and skip the generation of personal keys.
git aliases (and sections in git configs) to the rescue!
add an alias (from command line):
git config --global alias.identity '! git config user.name "$(git config user.$1.name)"; git config user.email "$(git config user.$1.email)"; :'
then, set, for example
git config --global user.github.name "your github username"
git config --global user.github.email your@github.email
and in a new or cloned repo you can run this command:
git identity github
This solution isn't automatic, but unsetting user and email in your global ~/.gitconfig
and setting user.useConfigOnly
to true
would force git to remind you to set them manually in each new or cloned repo.
git config --global --unset user.name
git config --global --unset user.email
git config --global user.useConfigOnly true
Although most questions sort of answered the OP, I just had to go through this myself and without even googling I was able to find the quickest and simplest solution. Here's simple steps:
.gitconfg
from your other repo.gitconfig
file, such as name, email and username
[user]
name = John
email = john@email.net
username = john133
.gitignore
list, to make sure you don't commit .gitconfig
file to your work repoHere are the complete steps after reading many answers here
How to set up Multiple SSH Keys settings for different github account
You might want to start checking your currently saved keys
$ ssh-add -l
If you decide to delete all cached keys before (optional, carefull about this)
$ ssh-add -D
Then you can create a ssh pub/priv key linked to each email/account that you wish/need to use
$ cd ~/.ssh
$ ssh-keygen -t rsa -C "work@company.com" <-- save it as "id_rsa_work"
$ ssh-keygen -t rsa -C "pers@email.com" <-- save it as "id_rsa_pers"
After performing this commands you will have the following files created
~/.ssh/id_rsa_work
~/.ssh/id_rsa_work.pub
~/.ssh/id_rsa_pers
~/.ssh/id_rsa_pers.pub
Make sure authentication agent is running
$ eval `ssh-agent -s`
Add the generated keys as following (from the ~/.ssh folder)
$ ssh-add id_rsa_work
$ ssh-add id_rsa_pers
Now you can check your saved keys again
$ ssh-add -l
Now you need to add the generated public keys to your github/bickbuket server Acces Keys
Clone each of the repos to different folders
Go to the folder where the user work will work and execute this
$ git config user.name "Working Hard"
$ git config user.email "work@company.com"
Just to see what this does check the contents of the ".git/config"
Go to the folder where the user pers will work and execute this
$ git config user.name "Personal Account"
$ git config user.email "pers@email.com"
Just to see what this does check the contents of the ".git/config"
After all this you will be able to commit your personal and work code by just switching between those two folders
In case you are using Git Bash and need to generate ssh keys under Windows follow this steps:
https://support.automaticsync.com/hc/en-us/articles/202357115-Generating-an-SSH-Key-on-Windows