Skip to main content

Folder Structure

Git includes the following files and folders:

tree -L 1 .git
.git
├── COMMIT_EDITMSG
├── FETCH_HEAD
├── HEAD
├── ORIG_HEAD
├── config
├── description
├── hooks
├── index
├── info
├── logs
├── objects
├── packed-refs
└── refs

5 directories, 8 files

config - file that includes configuration of the git repo, has info such as

  • core - default configs
  • remote - configured remotes
  • branch- the different branches

HEAD - file includes the reference to the head

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

git Objects\n\nGit has its own file system and objects

The type of objects:

  • Blob: represents a file of any type.
  • Tree: directories, can contain blobs or other trees.
  • Commit: Store versions of the project.
  • Annotated Tag: persistent text pointer to specific Commit..
commit -> tree -> N blobs/trees

Low-level commands to interact with git objects:

# Step 1) Create a blob and tree inside repo
# create a git object
# git uses SHA1 hash function
git hash-object



# creates a file in `.git/objects/b7/aec520dec0a7516c18eb4c68b64ae1eb9b5a5e`
echo "Hello, Git" | git hash-object --stdin -w\nb7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e


# creates a git object based on file
git hash-object /path/to/file -w


# read a git object
git cat-file

# contents of the object
git cat-file -p $HASH
git cat-file -p b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e\nHello, Git


# size of object
git cat-file -s b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e
11

# type of object
git cat-file -t b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e
blob


# Git Objects store the size, type and content within it
# and have the following structure:
$TYPE $SIZE\\0$CONTENT

echo "blob 11\\0Hello, Git" | shasum
b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e


# create a tree
echo "Hello, Git" | git hash-object --stdin -w
b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e
echo 'Hello, Git!' | git hash-object --stdin -w
670a245535fe6316eb2316c1103b1a88bb519334

# trees contain the file permissions, the type of pointer to the child blob/tree, the hash of the blob/tree and the filename with extension

cat temp-tree.txt
100644 blob b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e file1.txt
100644 blob 670a245535fe6316eb2316c1103b1a88bb519334 file2.txt

cat temp-tree.txt | git mkdir
9d2ce41b82297aad442e3187d87ce6ee9232f657

# Step 2) Move tree to staging
git read-tree $HASH_TREE
git read-tree 9d2c[41b82297aad442e3187d87ce6ee9232f657]

# list all files in staging area
git ls-files -s
100644 b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e 0 file1.txt
100644 670a245535fe6316eb2316c1103b1a88bb519334 0 file2.txt

# Step 2) Move tree to working directory
git checkout-index -a

What is a Commit

It's a git object type (1 of 4).

It has the same structure as other git objects:

Content + Object Type + Object Length = Hash

Every commit has the following information in its contents:

  • Author name and email
  • Commit description
  • Parent (optional)
  • Pointer hash to tree

The commit object is a wrapper to the tree object that has a pointer (hash) of the tree.

When committing changes that are in the staging area, we will see that hash of the commit:

# list files in staging
git ls-files -s
100644 b7aec520dec0a7516c18eb4c68b64ae1eb9b5a5e 0 file1.txt
100644 670a245535fe6316eb2316c1103b1a88bb519334 0 file2.txt


# cc83ae1 is the hash of this commit
git commit -m "very first commit"
[master (root-commit) cc83ae1] first commit
2 files changed, 2 insertions(+)
create mode 100644 file1.txt
create mode 100644 file2.txt

We can see the contents of the commit:

git cat-file -p cc83

# the hash that points back to the tree being wrapped by commit
tree 9d2ce41b82297aad442e3187d87ce6ee9232f657
author $NAME $EMAIL 1633710080 +0300
committer $NAME $EMAIL 1633710080 +0300

very first commit

If there is another commit based on the first one (cc83ae1), it will be seen in parent:

git --no-pager log
commit 4e7b9a4b17d4748f79e033264f89abb537e3047d (HEAD -> master)
Author: Me <email>
Date: Sat Oct 9 01:06:08 2021 +0300
second commit
commit cc83ae14f363a62b08df4afb719bf87fc57ddd95
Author: Me <email>
Date: Fri Oct 8 19:21:20 2021 +0300

first commit


git cat-file -p 4e7b9a
tree a9d0efa22cfef4b6b6805e35c9f4ef61d71f9d19
parent cc83ae14f363a62b08df4afb719bf87fc57ddd95
author Me <email> 1633730768 +0300
committer Me <email> 1633730768 +0300

second commit