Is it possible to have different Git configuration for different projects?
GitGit ConfigGit Problem Overview
.gitconfig
is usually stored in the user.home
directory.
I use a different identity to work on projects for Company A and something else for Company B (primarily the name / email). How can I have two different Git configurations so that my check-ins don't go with the name / email?
Git Solutions
Solution 1 - Git
There are 3 levels of git config; project, global and system.
- project: Project configs are only available for the current project and stored in .git/config in the project's directory.
- global: Global configs are available for all projects for the current user and stored in ~/.gitconfig.
- system: System configs are available for all the users/projects and stored in /etc/gitconfig.
Create a project specific config, you have to execute this under the project's directory:
$ git config user.name "John Doe"
Create a global config:
$ git config --global user.name "John Doe"
Create a system config:
$ git config --system user.name "John Doe"
And as you may guess, project overrides global and global overrides system.
Note: Project configs are local to just one particular copy/clone of this particular repo, and need to be reapplied if the repo is recloned clean from the remote. It changes a local file that is not sent to the remote with a commit/push.
Solution 2 - Git
As of git version 2.13, git supports conditional configuration includes. In this example we clone Company A's repos in ~/company_a
directory, and Company B's repos in ~/company_b
.
In your .gitconfig
you can put something like this.
[includeIf "gitdir:~/company_a/"]
path = .gitconfig-company_a
[includeIf "gitdir:~/company_b/"]
path = .gitconfig-company_b
Example contents of .gitconfig-company_a (the core section can be omitted if the global ssh key can be used)
[user]
name = John Smith
email = [email protected]
[core]
sshCommand = ssh -i ~/.ssh/id_rsa_companya
Example contents of .gitconfig-company_b
[user]
name = John Smith
email = [email protected]
[core]
sshCommand = ssh -i ~/.ssh/id_rsa_companyb
Solution 3 - Git
The .git/config
file in a particular clone of a repository is local to that clone. Any settings placed there will only affect actions for that particular project.
(By default, git config
modifies .git/config
, not ~/.gitconfig
- only with --global
does it modify the latter.)
Solution 4 - Git
Thanks @crea1
A small variant:
As it is written on https://git-scm.com/docs/git-config#_includes:
> If the pattern ends with /
, **
will be automatically added. For example, the pattern foo/
becomes foo/**
. In other words, it matches foo
and everything inside, recursively.
So I use in my case,
~/.gitconfig :
[user] # as default, personal needs
email = [email protected]
name = bcag2
[includeIf "gitdir:~/workspace/"] # job needs, like workspace/* so all included projects
path = .gitconfig-job
# all others section: core, alias, log…
So If the project directory is in my ~/wokspace/
, default user settings is replace with
~/.gitconfig-job :
[user]
name = John Smith
email = [email protected]
Solution 5 - Git
To be explicit, you can also use --local
to use current repository config file:
git config --local user.name "John Doe"
Or as @SherylHohman mentioned, use the following to open the local file in your editor:
git config --local --edit
Solution 6 - Git
I am doing this for my email in the following way:
git config --global alias.hobbyprofile 'config user.email "[email protected]"'
Then when I clone a new work project, I have only to run git hobbyprofile
and it will be configured to use that email.
Solution 7 - Git
Another way is to use direnv and to separate config files per directory. For example:
.
├── companyA
│ ├── .envrc
│ └── .gitconfig
├── companyB
│ ├── .envrc
│ └── .gitconfig
└── personal
├── .envrc
└── .gitconfig
Each .envrc
should contain something like this:
export GIT_CONFIG_GLOBAL=$(pwd)/.gitconfig
And .gitconfig
is usual gitconfig with desired values.
This is what I actually have in the custom .gitconfig
files:
[user]
email = [email protected]
[include]
path = ~/.gitconfig
Here only user.email
is overwritten, the rest configuration is taken from the default ~/.gitconfig
.
Solution 8 - Git
You can also point the environment variable GIT_CONFIG
to a file that git config
should use. With GIT_CONFIG=~/.gitconfig-A git config key value
the specified file gets manipulated.
Solution 9 - Git
You can customize a project's Git config by changing the repository specific configuration file (i.e. /path/to/repo/.git/config
). BTW, git config
writes to this file by default:
cd /path/to/repo
git config user.name 'John Doe' # sets user.name locally for the repo
I prefer to create separate profiles for different projects (e.g. in ~/.gitconfig.d/
) and then include them in the repository's config file:
cd /path/to/repo
git config include.path '~/.gitconfig.d/myproject.conf'
This works well if you need to use the same set of options in multiple repos that belong to a single project. You can also set up shell aliases or a custom Git command to manipulate the profiles.
Solution 10 - Git
Follow the Steps:
-
Find .gitconfig from the system
File Location For Windows : "C:\Users${USER_NAME}.gitconfig"
File Location For Linux : "/usr/local/git/etc/gitconfig"
-
Open .gitconfig file and add below lines as per your condition
[includeIf "gitdir:D:\ORG-A-PROJECTS\"] [user] name = John Smith email = [email protected] [includeIf "gitdir:~/organization_b/"] [user] name = John Doe email = [email protected]
Solution 11 - Git
I'm in the same boat. I wrote a little bash script to manage them. https://github.com/thejeffreystone/setgit
#!/bin/bash
# setgit
#
# Script to manage multiple global gitconfigs
#
# To save your current .gitconfig to .gitconfig-this just run:
# setgit -s this
#
# To load .gitconfig-this to .gitconfig it run:
# setgit -f this
#
#
#
# Author: Jeffrey Stone <[email protected]>
usage(){
echo "$(basename $0) [-h] [-f name]"
echo ""
echo "where:"
echo " -h Show Help Text"
echo " -f Load the .gitconfig file based on option passed"
echo ""
exit 1
}
if [ $# -lt 1 ]
then
usage
exit
fi
while getopts ':hf:' option; do
case "$option" in
h) usage
exit
;;
f) echo "Loading .gitconfig from .gitconfig-$OPTARG"
cat ~/.gitconfig-$OPTARG > ~/.gitconfig
;;
*) printf "illegal option: '%s'\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
esac
done
Solution 12 - Git
I had an error when trying to git stash
my local changes. The error from git said "Please tell me who you are" and then told me to "Run git config --global user.email "[email protected]
and git config --global user.name "Your name"
to set your account's default identity." However, you must Omit --global to set the identity only in your current repository.
Solution 13 - Git
Add multiple SSH keys with Github config
After 13 August 2021, git is not supporting HTTPs authentication method, so I believe this answer needs to be updated.
Follow the steps below:
- remove all SSH keys (public & private) for Git stored in directory
~/.ssh/
. - create new SSH keys:
ssh-keygen -t rsa -b 4096 -C "[email protected]"
ssh-keygen -t rsa -b 4096 -C "[email protected]"
When asked for file names, give default ~/.ssh/id_rsa
for account1 and ~/.ssh/id_rsa_acc2
for account2 respectively.
- Star ssh-agent and add private keys for account1 and account2:
eval `ssh-agent -s
ssh-add -k ~/.ssh/id_rsa
ssh-add -k ~/.ssh/id_rsa_acc2
confirm keys are added by command ssh-add -l
-
copy public keys for account1 and account2 and add it to your github account.
-
set account1's username and user email as global GitHub config:
git config --global user.name "acc1_username"
git config --global user.email "[email protected]"
- create
~/.ssh/config
file with following configuration:
# account1 github
Host github.com
HostName github.com
User git
AddKeysToAgent yes
IdentityFile ~/.ssh/id_rsa
# account2 github
Host github.com-acc2
HostName github.com
User git
AddKeysToAgent yes
IdentityFile ~/.ssh/id_rsa_acc2
- To set GitHub account2 for a project set username & email on project level in the project root directory:
git config user.name "acc2_username"
git config user.email "[email protected]"
- Now clone or add origin by using SSH link of GitHub repo:
# for account1 repo
git remote set-url origin [email protected]:acc1_username/reponame.git
# for account2 repo
git clone [email protected]:acc2_username/reponame.git
Feel free to add comments for any doubts.
Solution 14 - Git
Found out a really useful shell script wrapping over all the process of ssh key generation and typing out long commands again and again
Note: This is only for ZSh
users