Skip to content

git

The basics in short, the basic picture.

configuration

The config is stored/read in these files :

  • /etc/gitconfig
  • ~/.gitconfig or ~/.config/git/config
  • project/.git/config

All settings are mixed, but if double the lower outranks the higher in the list. To see where settings are taken from :

show configuration list
git config --list --show-origin

possible output :

output
file:/home/kees/.gitconfig      user.name=kees
file:/home/kees/.gitconfig      user.email=kees@klopt.org
file:/home/kees/.gitconfig      merge.tool=meld
file:/home/kees/.gitconfig      color.ui=auto
file:/home/kees/.gitconfig      http.cookiefile=/home/kees/.gitcookies
file:.git/config        core.repositoryformatversion=0
file:.git/config        core.filemode=true
file:.git/config        core.bare=false
file:.git/config        core.logallrefupdates=true
file:.git/config        remote.origin.url=file:///home/kees/repo
file:.git/config        remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
file:.git/config        branch.master.remote=origin
file:.git/config        branch.master.merge=refs/heads/master
file:.git/config        gui.wmstate=normal
file:.git/config        gui.geometry=1547x998+139+96 376 212

git init

This turns a directory into a working copy, with no tracked files yet. It creates a directory structure like this :

init
tree .git
.git/
├── branches                            # empty branches dir
├── config                              # default config file
├── description                         # std description sentence
├── HEAD                                # contains "ref: refs/heads/master"
├── hooks                               # example hook scripts
   ├── applypatch-msg.sample           # when you remove the .sample
   ├── commit-msg.sample               # part of these scripts
   ├── fsmonitor-watchman.sample       # they could be fired on 
   ├── post-update.sample              # certain actions
   ├── pre-applypatch.sample
   ├── pre-commit.sample
   ├── pre-merge-commit.sample
   ├── prepare-commit-msg.sample
   ├── pre-push.sample
   ├── pre-rebase.sample
   ├── pre-receive.sample
   └── update.sample
├── info
   └── exclude                         # exclude patters 
├── objects                             # empty objects directories
   ├── info
   └── pack
└── refs                                # emprt refs directories
    ├── heads
    └── tags

I also added three files in this directory : a, b and c If you add one, it will trigger these changes(unchanged files/directories deleted)

add sources
1
2
3
4
5
6
7
8
git add a
tree .git
├── index           # new 
├── objects         # objects not empty anymore 
   ├── 78
      └── 981922613b2afb6025042ff6bd878ac1994e85
   ├── info
   └── pack

The index is an unreadable binary file, but you can imagine it now has a in it's index and some data accompanying it. It probably says where it resides in the object tree. The object 78 also is a binary file unreadable to humans.

If we now commit :

commit
git commit
tree .git
├── COMMIT_EDITMSG
├── logs
   ├── HEAD
   └── refs
       └── heads
           └── master
├── objects
   ├── 5e
      └── 31ac20d128c5ca38bf2e3fcbda24fe9386b010
   ├── 78
      └── 981922613b2afb6025042ff6bd878ac1994e85
   ├── aa
      └── ff74984cccd156a469afa7d9ab10e4777beb24

The changes are, an added commit message, which is readable and exactly what you typed when committing the file. logs is now created also with readable text (both HEAD and refs/head/master are exactly the same) :

logs
0000000000000000000000000000000000000000 5e31ac20d128c5ca38bf2e3fcbda24fe9386b010 kees <kees@klopt.org> 1585672229 +0200    commit (initial): commited a

The new objects are again unreadable. One extra detail is that refs/head now contains 'master' containing (only) the hash from the logs file :

refs/head
5e31ac20d128c5ca38bf2e3fcbda24fe9386b010

Note that if you now alter file a it does not have to be added again. It remains tracked from now until you delete it. You do have to mention what to commit though by either specifying a or using -a (all)

commit specific or all
git commit a
git commit -a

The git tree now contains more objects and the logs gets added to :

logs
0000000000000000000000000000000000000000 5e31ac20d128c5ca38bf2e3fcbda24fe9386b010 kees <kees@klopt.org> 1585672229 +0200    commit (initial): commited a
5e31ac20d128c5ca38bf2e3fcbda24fe9386b010 c55712d0cec11f4f55ac7516552c138f74bc6ec0 kees <kees@klopt.org> 1585672827 +0200    commit: changed a

The first number clearly means 'last hash' and the second means 'this hash' The objects now contain more entries, mostly there will be three per file :

  • a blob file
  • a tree file
  • a commit file

What exactly they do goes too deep , see here if you want to know more : visit

Though i could not get many commands in there to work, this one that lists the objects and their type does :

list objects
# traverses downwards
git cat-file --batch-all-objects --batch

Best docs : visit It is also a book :

The Book <progit.pdf>

For lfs : visit