Mog is my own implementation of Git, built from scratch in C++. 🚀
There are broadly two types of commands in git:
- Porcelain Commands: High-level commands that users interact with directly (e.g.,
git add
,git commit
,git push
) - Plumbing Commands: Low-level commands that interact with the Git database (e.g.,
git hash-object
,git cat-file
,git update-ref
)
Mog focuses on the plumbing commands and aims to provide a basic understanding of how Git works under the hood. It supports the following plumbing commands:
mog init
: Initialize a new Git repositorymog hash-object <file>
: Compute the hash of a file and store it in the Git databasemog cat-file <hash>
: Retrieve and display the contents of a Git objectmog write-tree
: Create a tree object from the current working directorymog read-tree <tree-hash>
: Read the contents of a tree object into the working directorymog commit-tree <tree-hash> [-p <parent-hash>]
: Create a commit object from a tree object
I wanted to understand how Git works under the hood, and I figured the best way to do that was to build my own implementation from the ground up. Along the way, I also deepened my knowledge of C++ and how to use it to develop a full-fledged application.
Git operates as a key-value store based on three primary object types:
- Blob Objects - Store file contents
- Tree Objects - Represent directories
- Commit Objects - Capture repository snapshots
A blob stores the contents of a file. Its format is:
blob <content-length>\0<content>
<content-length>
: The length of the file content in bytes<content>
: The actual file content
A tree stores information about directories and the files they contain. Its format is:
tree <content-length>\0<entry>
Each entry in a tree object follows this structure:
<mode> <filename>\0<hash>
<mode>
: File mode (permissions)<filename>
: Name of the file or directory<hash>
: SHA-1 hash of the corresponding blob or tree object
A commit represents a snapshot of the repository at a specific point in time. Its format is:
commit <content-length>\0<commit-content>
The commit content includes:
tree <tree-hash>
parent <parent-hash>
author <author>
committer <committer>
<commit-message>
<tree-hash>
: Reference to the tree object representing the state of the repository<parent-hash>
: Reference to the previous commit (optional for the first commit)<author>
: The person who created the commit<committer>
: The person who committed the changes<commit-message>
: A message describing the commit