Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Oh, Git Configurations! Let's Simplify It

DZone's Guide to

Oh, Git Configurations! Let's Simplify It

Learn where exactly to find your git configuration files by going inside the mind of Linus Torvalds to better understand how git is organized.

· DevOps Zone ·
Free Resource

Read why times series is the fastest growing database category.

Oh, Git Is Complex!

Git is a complex system. To see the proof, check out:

  1. ohshitgit.com
  2. gitfightrules.com

To mitigate that, we are going to get inside the head of Linus Torvalds! (Just a little bit - maybe into a single neuron). In this part, we will focus on configurations. I always thought that to understand a system, I needed to understand its configurations (or even better, its installation).

When I get to a new company, the first thing I try to figure out is:

  1. How do I install this?
  2. How do I configure this?

How Does Linus Torvalds Think?

"Everything is a file."

Yes, this is how Linus thinks: everything is a file.

As Linus loves this idea that everything is a file, you can just view git configurations as a file.

So, if we manage to learn which files Linus uses in git, we might be able to penetrate oh-my-complex-git!

3 Fallback Layers of Config

  1. System - Your OS git config - git config --system
  2. Global - Your User git config - git config --global
  3. Local - Your Repository git config - git config --local
git config --system # => /etc/gitconfig

git config --glboal # => ~/.gitconfig or ~/.config/git/config

git config --local # => .git/config

Git first reads the git config from .git/config -> [fallback to] ~/.gitfconfig -> [fallback to] /etc/gitconfig.

Email per Repo

If you have different email addresses for different repositories, this goes into .gitconfig == git config --local

Get the Global Config With git config --list --global

➜  tmp git config --list --global

user.name=Tomer Ben David
user.email=tomer.bendavid@ohohoh.com
core.autocrlf=input
format.pretty=format:%h %Cblue%ad%Creset %ae %Cgreen%s%Creset

Would that be the same as cat ~/.gitconfig? What do you think?

➜  tmp cat ~/.gitconfig
[user]
    name = Tomer Ben David
    email = tomer.bendavid@ohohoh.com
[core]
    autocrlf = input
[format]
  pretty = format:%h %Cblue%ad%Creset %ae %Cgreen%s%Creset

Yes and no! It's a different notation, but generally the same!

Get the Merged Config With git config --list

The merged config is the combination of all configs with the hierarchy. Let's see it on my machine:

git config --list

➜  tmp git config --list
core.excludesfile=~/.gitignore
core.legacyheaders=false
core.quotepath=false
mergetool.keepbackup=true
push.default=simple
color.ui=auto
color.interactive=auto
repack.usedeltabaseoffset=true
alias.s=status
alias.a=!git add . && git status
alias.au=!git add -u . && git status
alias.aa=!git add . && git add -u . && git status
alias.c=commit
alias.cm=commit -m
alias.ca=commit --amend
alias.ac=!git add . && git commit
alias.acm=!git add . && git commit -m
alias.l=log --graph --all --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'
alias.ll=log --stat --abbrev-commit
alias.lg=log --color --graph --pretty=format:'%C(bold white)%h%Creset -%C(bold green)%d%Creset %s %C(bold green)(%cr)%Creset %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
alias.llg=log --color --graph --pretty=format:'%C(bold white)%H %d%Creset%n%s%n%+b%C(bold blue)%an <%ae>%Creset %C(bold green)%cr (%ci)' --abbrev-commit
alias.d=diff
alias.master=checkout master
alias.spull=svn rebase
alias.spush=svn dcommit
alias.alias=!git config --list | grep 'alias\.' | sed 's/alias\.\([^=]*\)=\(.*\)/\1\     => \2/' | sort
include.path=~/.gitcinclude
include.path=.githubconfig
include.path=.gitcredential
diff.exif.textconv=exif
credential.helper=osxkeychain
user.name=Tomer Ben David
user.email=tomer.bendavid@ohohohoh.com
core.autocrlf=input
format.pretty=format:%h %Cblue%ad%Creset %ae %Cgreen%s%Creset

That was it - all the git config on my machine! I hope I didn't put any passwords in there! If I did please, let me know - code review is important, guys!

Git Config --local/global/system user.name - Get a Single Config

Ask layer by layer for a config:

➜  tmp git config --local user.name
fatal: BUG: setup_git_env called without repository # We called from a non-repository folder.
➜  tmp git config --global user.name
Tomer Ben David
➜  tmp git config --system user.name # => nothing in the global config file.
➜  tmp

Aha! So it's coming from the global (user) config!

Note that in the file, it's with [user] and the name, and the git config returns the combined name user.name.

If you need a hierarchy larger than three, then in the file, it will look like this:

[branch "gke"]
    remote = origin
    merge = refs/heads/gke

So, this one should be branch.gke.remote. Let's verify this:

➜  .git git:(gke) git config branch.gke.remote # => yes it is branch.gke.remote!
origin


Set a New Config With git config mysection.mykey myvalue

➜  .git git:(gke) git config mysection.mykey myvalue
➜  .git git:(gke) git config mysection.mykey
myvalue

So, we were able to set it. Let's look at the file:

➜  .git git:(gke) cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "origin"]
    url = https://bitbucket.org/yshenbaum/k8s-course.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "gke"]
    remote = origin
    merge = refs/heads/gke
[mysection] ##### =====> Here it is! see the section in []
    mykey = myvalue


Summary

You now know exactly where your git config files are. This is very helpful and much more explainable than using the git commands. I'm not sure I was able to simplify it, but it makes at least some sense at the end of the day for us programmers!

Resources

Ry's Git Tutorial here is my BOOK Review

Learn how to get 20x more performance than Elastic by moving to a Time Series database.

Topics:
devops ,git ,software development ,linux

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}