Git under the hood

Page content

Materials

Object types in Git

  1. Blob
  2. Tree
  3. Commit
  4. Tag <= Skip in this post

These objects are stored in .git/objects/.

How to read the objects

Git objects are compressed.

# Get file information
$ git ls-files -s {{ my_git-managed_file }}
100644 4be0b2b8b0fd36b8b3c94c46b4af4cfb2558d11c 0 {{ my_git-managed_file }}

# Decompress the Git object
$ pigz -d < .git/objeccts/4b/e0b2b8b0fd36b8b3c94c46b4af4cfb2558d11c 
blob 7572my Markdown file!!

# Another object (tree)
$ git ls-tree HEAD
// --- snipp --- //
040000 tree 423d17368f16ff18aac8ee494e27bafef8587afa	content

$ pigz -d < .git/objects/42/3d17368f16ff18aac8ee494e27bafef8587afa | head -1
tree 156240000 AWSԀ��D*�1�v�&R�m�0000 GCP�H��K���k�9K�Z40000 GitLab���


# Another object (commit)
$ git rev-parse HEAD^
66c66690a54ea41e6902ba5317f10c4095e3d78a

$ pigz -d < .git/objects/66/c66690a54ea41e6902ba5317f10c4095e3d78a 
commit 223tree dd84fe98a7daa7955a043b67717e2078cf972b4e
parent 6eb0c354c0d996444fa2df1213d9fa11fe981ead
author atlex00 <atlex00@gmail.com> 1634302147 +0200
committer atlex00 <atlex00@gmail.com> 1634302147 +0200

Rust book section 14
  • The ID of a blob is SHA-1 hash of the content.
  • The object type of normal files is “blob” and, the object type of directories is “tree”.
  • Tree objects point to blobs or other trees.

What happend when you commit changes?

Refer to the slideshare link.

  1. You commit your changes.
  2. Git creates the commit object.
  3. It creates a new root tree.
  4. If a file was changed, create a new blob object. If a file wasn’t changed, the tree will refer a original blob.
    • which means, Git saves the whole file.
  5. The new trees and blobs are created for the new commit.

Branches, HEAD

Branches and HEAD are just pointers to a commit.

https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified

HEAD is the pointer to the current branch reference, which is in turn a pointer to the last commit made on that branch. That means HEAD will be the parent of the next commit that is created. It’s generally simplest to think of HEAD as the snapshot of your last commit on that branch.

Blobs, trees, commits, tags are immutable Git objects, and HEAD and branchs are mutable Git references.