Like any other tools, git can be configured.
You can script those configurations and store them at different places within configuration files.
This article answers the following questions:
(1) Why using git configuration? What is that useful for?
(2) What can I configure and how?
(3) What a configuration file might look like?
It will also present you with a use-case to store different git user profiles and there specific ssh keys.
Why using git config?
Having git configurations stored in place allows you to (1) have a nice commit history with your user information displayed on Github or Gitlab’s UI. It is a way to reconciliate the user stored on the remote with the user stored on your local.
It provides also a (2) handy way to share configuration like git aliases (see this article).
Last but not the least, it allows you to (3) have different config (e.g. ssh and user identification) if you want for instance to switch users if you are multi-tenant (e.g. your ssh key to connect for Gitlab or Github might be different. Same for the email and username in used).
Anatomy of a configuration file
A git config file is a simple file. It can have different names depending on where it is located. Generally when located at the root, the name will be .gitconfig
.
zsh> tail -n 3 ~/.gitconfig
[user]
name = John Doe
email = john.doe@gmail.com
The data in there are written like in a toml file.
A git config file has different sections. The default one is [core]. Another useful one is [user].
Alias are put under the alias section.
Here is an example of what a simple .gitconfig file might look like:
[alias]
p=pull
c=commit
cm=commit -m
s=status
sw=switch
a=add
alias=!git config -l | grep alias | cut -c 7-
cam=commit -am
lo=log --oneline
sc=switch -c
rsm=rm -r --cached
asm=submodule add
[user]
name = John Doe
email = "john.doe@gmail.com"
More here: https://git-scm.com/docs/git-config#_configuration_file
The different configuration scopes (global, local)
By default, git config will read the configuration options from different git config files in that order:
(1) /etc/gitconfig
(2) ~/.gitconfig
(3) .git/config (at the repository level)
(4) .git/config.worktree (at the repository level)
They are also overwritten in that order. The local one taking precedence over the global configurations.
To read all the current configurations, you can either cat
those files or simply run:
zsh> git config --list --show-scope --show-origin
Note: the show-origin argument will list where the config comes from.
If you want to see what are the specific values hold for the current config (depending on your pwd) you can use the get
argument:
zsh> git config --get user.name
John Doe
zsh> git config --get user.email
john.doe@gmail.com
Note: depending on where you are located – i.e. the working directory – the value returned by the get
command might change.
For instance, let’s say you have two git configuration files with different configuration in place:
zsh> pwd
~/my-workplace-folder
zsh> tree -a .
.
├── .git
└── config
├── git-project-A
└── git-project-B
zsh> cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
name = Jane Doe
email = jane.doe@gmail.com
zsh> git config user.name
Jane Doe
zsh> git config --global user.name
John Doe
zsh> cat ~/.gitconfig
[user]
name = John Doe
email = john.doe@gmail.com
You can also edit the git config files via command lines:
zsh> pwd
~/my-workplace-folder
zsh> git config --local user.name "Baby Doe"
zsh> git config --local user.email "baby.doe@gmail.com"
zsh> tail -n 3 .git/config
[user]
name = Baby Doe
email = baby.doe@gmail.com
zsh> git config --get user.name
Baby Doe
zsh> git config --global --get user.name
John Doe
One important note when setting value via command line though:
If you add an equal e.g. git config --local user.name = "Baby Doe"
, the “=” char will be interpreted by the command as the string value passed to user.name and will ignore silently the rest of the line. You will end up with the following file:
ssh> cat .git/config
[user]
name = =
Thus, make sure to write this instead:
zsh> git config --local user.name "Baby Doe"
Use-case: different git user profiles
I have a gitlab/ folder and a github/ one.
zsh> tree .
├── github/
└── gitlab/
By default, I want my git config (user name and email) to be associated with gitlab.
However, I want those config to be overwritten when my working directory if under the github/ folder.
Note that because I want those two users to be able to ssh push and pull from the remote repositories, they both have a specific ssh key configured:
zsh> ls -la ~/.ssh
id_rsa_gitlab
id_rsa_gitlab.pub
id_rsa_gitlhub
id_rsa_github.pub
Note: you can create a new ssh key running:
zsh> sh-keygen -o -t rsa -C "gitlab@gmail.com"
Step 1 – in the global ~/.gitconfig file:
[user]
name = "Gitlab User"
email = "gitlab@gmail.com"
[includeIf "gitdir:~/github/"]
path = ~/github/.gitconfig
Step 2 – in the github/ folder:
zsh> git init # create the .git folder
zsh> cat <<EOT >> .gitconfig
[core]
sshCommand = "ssh -i ~/.ssh/id_rsa_github"
[user]
name = "Github User"
email = "github@gmail.com"
EOT
zsh> pwd
~/github/
zsh> git config user.name
Github User
zsh> cd ~/gitlab
zsh> git config user.name
Gitlab User
Note: withing the github/ folder, one must remain careful and keep in mind in case of overlapping issues that there is therefore now two git config files, one being .gitconfig
and the second one being .git/config
.