Git Internals:
The .git directory
Goals
- Learn about the structure of the
.git
directory
The .git
Directory
Time to do some exploring. First, from the root of your project directory…
Execute:
ls -C .git
Output:
$ ls -C .git
COMMIT_EDITMSG config index objects
HEAD description info refs
ORIG_HEAD hooks logs
This is the magic directory where all the git “stuff” is stored. Let’s peek in the objects directory.
The Object Store
Execute:
ls -C .git/objects
Output:
$ ls -C .git/objects
09 27 42 59 6b 7a 9c b5 e4 pack
11 28 43 5a 72 90 af c4 e7
24 30 44 69 78 97 b0 c8 info
You should see a bunch of directories with 2 letter names. The directory names are the first two letters of the sha1 hash of the object stored in git.
Deeper into the Object Store
Execute:
ls -C .git/objects/<dir>
Output:
$ ls -C .git/objects/09
6b74c56bfc6b40e754fc0725b8c70b2038b91e 9fb6f9d3a104feb32fcac22354c4d0e8a182c1
Look in one of the two-letter directories. You should see some files with 38-character names. These are the files that contain the objects stored in git. These files are compressed and encoded, so looking at their contents directly won’t be very helpful, but we will take a closer look in a bit.
Config File
Execute:
cat .git/config
Output:
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
name = Jim Weirich
email = jim (at) edgecase.com
This is a project-specific configuration file. Config entries in here will override the config entries in the .gitconfig
file in your home directory, at least for this project.
Branches and Tags
Execute:
ls .git/refs
ls .git/refs/heads
ls .git/refs/tags
cat .git/refs/tags/v1
Output:
$ ls .git/refs
heads
tags
$ ls .git/refs/heads
master
$ ls .git/refs/tags
v1
v1-beta
$ cat .git/refs/tags/v1
4254c9466673a6ddbeb35e2802315dbcfc1dbb62
You should recognize the files in the tags subdirectory. Each file corresponds to a tag you created with the git tag
command earlier. Its content is just the hash of the commit tied to the tag.
The heads directory is similar, but is used for branches rather than tags. We only have one branch at the moment, so all you will see is master in this directory.
The HEAD File
Execute:
cat .git/HEAD
Output:
$ cat .git/HEAD
ref: refs/heads/master
The HEAD file contains a reference to the current branch. It should be a reference to master at this point.