Inside .git directory

Tomasz Kołodziej

GIT

"the stupid content tracker"

Linus Torvalds

.git

$ ls .git
branches        
description  
HEAD   
info     
COMMIT_EDITMSG  
hooks  
logs     
packed-refs
config   
index  
objects  
refs

.git/objects

"Git is a content-addressable filesystem"

.git/objects

$ git init
Initialized empty Git repository in /wwwdocs/hello/.git/

$ echo "hello world" >> readme.md

$ git add readme.md 

$ git commit -m "Initial commit"
[master (root-commit) 119a70e] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 readme.md

.git/objects

$ find .git/objects/
.git/objects/
.git/objects/11
.git/objects/11/9a70e0cbfe67050a29311f521b0e85e63bdb45
.git/objects/73
.git/objects/73/94b8cc9ca916312a79ce8078c34b49b1617718
.git/objects/3b
.git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad
.git/objects/info
.git/objects/pack

.git/objects - blob

$ cat .git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad 
xK��OR04b�H���W(�/�I�D�
$ cat .git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad 
| zlib-flate -uncompress
blob 12hello world
$ cat .git/objects/3b/18e512dba79e4c8300dd08aeb37f8e728b8dad 
| zlib-flate -uncompress | sha1sum
3b18e512dba79e4c8300dd08aeb37f8e728b8dad  -

.git/objects - tree

$ git cat-file 7394b8cc9ca916312a79ce8078c34b49b1617718 -t
tree

$ git cat-file 7394b8cc9ca916312a79ce8078c34b49b1617718 -p
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad	readme.md
$ git write-tree
7394b8cc9ca916312a79ce8078c34b49b1617718

.git/objects - commit

$ cat .git/objects/11/9a70e0cbfe67050a29311f521b0e85e63bdb45  
| zlib-flate -uncompress

commit 201tree 7394b8cc9ca916312a79ce8078c34b49b1617718
author TK <tomasz.kolodziej@esky.pl> 1425329812 +0100
committer TK <tomasz.kolodziej@esky.pl> 1425329812 +0100

Initial commit
$ git commit -m "Initial commit"
[master (root-commit) 119a70e] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 readme.md

.git/objects

.git/objects/pack

$ git gc
Counting objects: 3, done.
Writing objects: 100% (3/3), done.
Total 3 (delta 0), reused 0 (delta 0)
$ ls .git/objects/
11  3b  73  info  pack
$ find .git/objects/
.git/objects/
.git/objects/info
.git/objects/info/packs
.git/objects/pack
.git/objects/pack/pack-89e0c61b00e0a1a6419038b7dba12c4796786e55.idx
.git/objects/pack/pack-89e0c61b00e0a1a6419038b7dba12c4796786e55.pack

.git/objects/pack

$ cat .git/objects/info/packs 
P pack-89e0c61b00e0a1a6419038b7dba12c4796786e55.pack

$ cat .git/objects/pack/pack-89e0c61b00e0a1a6419038b7dba12c4796786e55.idx 
�tOc�p���g
)1R��;�E;�ۧ�L������s��̜�1*y΀x�KI�awB.7cr�� LR�
                                                    ��ࡦA�8�ۡ,G�xnU�tf����@Y��d�2��
$ git verify-pack --verbose 
  .git/objects/pack/pack-89e0c61b00e0a1a6419038b7dba12c4796786e55.idx 

119a70e0cbfe67050a29311f521b0e85e63bdb45 commit 201 131 12
7394b8cc9ca916312a79ce8078c34b49b1617718 tree   37 48 143
3b18e512dba79e4c8300dd08aeb37f8e728b8dad blob   12 21 191
non delta: 3 objects
.git/objects/pack/pack-89e0c61b00e0a1a6419038b7dba12c4796786e55.pack: ok

.git/objects

$ mkdir docs
$ cp readme.md docs/

$ git add docs/readme.md 
$ git write-tree
a2de95ff7252c7ff918afd890602f58793003ea3

$ ls .git/objects/
a2  info  pack
$ git cat-file a2de -p
040000 tree 7394b8cc9ca916312a79ce8078c34b49b1617718	docs
100644 blob 3b18e512dba79e4c8300dd08aeb37f8e728b8dad	readme.md

.git/objects

$ git mv readme.md readme2.md 
$ echo "Bye bye" > readme2.md 
$ git add readme2.md 
$ git status
HEAD detached at 119a70e
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    readme.md -> docs/readme.md
	new file:   readme2.md

.git/objects

$ git commit -m "Second commit"
[detached HEAD 57c068d] Second commit
 2 files changed, 1 insertion(+)
 rename readme.md => docs/readme.md (100%)
 create mode 100644 readme2.md
$ git cat-file 57c0 -p
tree ac49095c05e3b606307a409579cd34136a0612d5
parent 119a70e0cbfe67050a29311f521b0e85e63bdb45
author Tomasz Kolodziej <tomasz.kolodziej@esky.pl> 1426282470 +0100
committer Tomasz Kolodziej <tomasz.kolodziej@esky.pl> 1426282470 +0100

Second commit

.git/objects

.git/index

"The index is a binary file containing a sorted list of path names"

.git/index

$ git ls-files --stage
100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0	docs/readme.md
100644 3d804f9b6d4ad5f269516d330431e875e3e560dc 0	readme2.md

$ echo "World says hello" > readme2.md
$ git status
On branch master
Changes not staged for commit:

	modified:   readme2.md

$ git diff
diff --git a/readme2.md b/readme2.md
index 3d804f9..27f6e23 100644
--- a/readme2.md
+++ b/readme2.md
@@ -1 +1 @@
-hello world
+World says hello

.git/index

$ git add readme.md
$ git status
On branch master
Changes to be committed:

	modified:   readme2.md

$ git ls-files --stage
100644 27f6e2314a88c32614856b03aa10036b8fd865c1 0	readme2.md
$ git update-index --cacheinfo 644 3d804f9b6d4ad5f269516d330431e875e3e560dc readme2.md
$ git diff
diff --git a/readme2.md b/readme2.md
index 3d804f9..27f6e23 100644
--- a/readme2.md
+++ b/readme2.md
@@ -1 +1 @@
-hello world
+World says hello

Jak to działa ?

$ git init
Initialized empty Git repository 
  in /wwwdocs/project/.git/

$ echo foo >> file1
$ echo bar >> file2
$ git add .

$ git write-tree
f9c36476895b0f9a475dfbaeb492332c63c148ec

$ git commit -m "First commit"
[master (root-commit) fa8ab9a] First commit
 2 files changed, 2 insertions(+)
 create mode 100644 file1
 create mode 100644 file2

Źródło: Jon Loeliger and Matthew McCullough  
 Version Control with Git - 2012

$ echo quux > file1

$ git add file1 

$ git write-tree
9c290d030cbd030967779eab1cb5ccf0cc166634

Źródło: Jon Loeliger and Matthew McCullough  
 Version Control with Git - 2012


$ git commit -m "second commit"
[master faa8038] second commit
 1 file changed, 1 insertion(+), 
 1 deletion(-)

Źródło: Jon Loeliger and Matthew McCullough  
 Version Control with Git - 2012

.git/branches

.git/branches

 "A slightly deprecated way to store shorthands"

$ find .git/branches/
.git/branches/

.git/refs

"the refs directory stores pointers into commit objects"

.git/refs

$ ls .git/refs

heads
remotes
tags

$ ls .git/refs/heads

master

$ cat .git/refs/heads/master 
faa80389dcb8ce9cc4fb743ef795578d0a532622

.git/refs

$ git branch feature/my-feature

$ cat .git/refs/heads/feature/my-feature
faa80389dcb8ce9cc4fb743ef795578d0a532622
$ git checkout non-existing-branch
error: pathspec 'non-existing-branch' did not match any file(s) known to git.
$ cp .git/refs/heads/master .git/refs/heads/non-existing-branch
$ git checkout non-existing-branch
Switched to branch 'non-existing-branch'

.git/refs

$ git branch feature/users
$ git branch feature/users/login-page
error: unable to resolve reference refs/heads/feature/users/list: Not a directory
fatal: Failed to lock ref for update: Not a directory

.git/refs

$ find .git/refs
...
.git/refs/heads
.git/refs/heads/master
.git/refs/heads/feature
.git/refs/heads/feature/my-feature
...
.git/refs/remotes
.git/refs/remotes/origin
.git/refs/remotes/origin/master
.git/refs/remotes/origin/feature
.git/refs/remotes/origin/feature-my-feature
...
.git/refs/remotes/central/pull-requests
.git/refs/remotes/central/pull-requests/289
.git/refs/remotes/central/pull-requests/289/merge
.git/refs/remotes/central/pull-requests/289/from
.git/refs/remotes/central/pull-requests/281
.git/refs/remotes/central/pull-requests/281/merge
.git/refs/remotes/central/pull-requests/281/from
...
.git/refs/tags
.git/refs/tags/0.1.1

.git/HEAD

The HEAD file is a symbolic reference to the branch you’re currently on.

.git/HEAD

$ cat .git/HEAD 
ref: refs/heads/master


$ git log --pretty=oneline
faa80389dcb8ce9cc4fb743ef795578d0a532622 second commit
fa8ab9ad6fcfc71b4f3163950261c47182c93012 First commit

.git/HEAD

$ git checkout fa8ab9
Note: checking out 'fa8ab9'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at fa8ab9a... First commit
$ cat .git/HEAD 
fa8ab9ad6fcfc71b4f3163950261c47182c93012

.git/HEAD

$ echo 'ref: refs/heads/master' > .git/HEAD
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   file1
$ git symbolic-ref HEAD refs/heads/master

.git/logs

 "Git silently records what your HEAD is every time you change it."

.git/logs

$ cat .git/logs/HEAD 

0000000000000000000000000000000000000000 fa8ab9ad6fcfc71b4f3163950261c47182c93012 
    TK <tomasz.kolodziej@esky.pl> 1425674471 +0100	commit (initial): First commit

fa8ab9ad6fcfc71b4f3163950261c47182c93012 faa80389dcb8ce9cc4fb743ef795578d0a532622 
    TK <tomasz.kolodziej@esky.pl> 1425844741 +0100	commit: second commit

faa80389dcb8ce9cc4fb743ef795578d0a532622 fa8ab9ad6fcfc71b4f3163950261c47182c93012 
    TK <tomasz.kolodziej@esky.pl> 1425846181 +0100	checkout: moving from master to fa8ab9

faa80389dcb8ce9cc4fb743ef795578d0a532622 faa80389dcb8ce9cc4fb743ef795578d0a532622 
    TK <tomasz.kolodziej@esky.pl> 1425848751 +0100	checkout: moving from master to custom-branch

faa80389dcb8ce9cc4fb743ef795578d0a532622 faa80389dcb8ce9cc4fb743ef795578d0a532622 
    TK <tomasz.kolodziej@esky.pl> 1425848780 +0100	checkout: moving from custom-branch to non-existing-branch

.git/logs

$ git reflog 
faa8038 HEAD@{0}: checkout: moving from custom-branch to non-existing-branch
faa8038 HEAD@{1}: checkout: moving from master to custom-branch
faa8038 HEAD@{2}: checkout: moving from master to fa8ab9
faa8038 HEAD@{3}: commit: second commit
fa8ab9a HEAD@{4}: commit (initial): First commit

.git/logs

$ cat .git/logs/refs/heads/master 

0000000000000000000000000000000000000000 fa8ab9ad6fcfc71b4f3163950261c47182c93012 
    TK <tomasz.kolodziej@esky.pl> 1425674471 +0100	commit (initial): First commit

fa8ab9ad6fcfc71b4f3163950261c47182c93012 faa80389dcb8ce9cc4fb743ef795578d0a532622 
    TK <tomasz.kolodziej@esky.pl> 1425844741 +0100	commit: second commit

Pytania ?

inside .git directory

By Tomasz Kołodziej

inside .git directory

  • 699