# A Deep Dive Into Git Internals

Earlier we came to know that Git takes snapshots of your codebase that it to manage/ track your code. Now, let’s see this from a technical perspective.  
Git assigns a unique 40 digit id to every Commit(the snapshot) known as a **SHA-1**(Secure Hash Algorithm). A SHA is:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1768848726855/35f08843-0543-4436-990b-b995781ce78e.png align="center")

This SHA is like a checkpoint on the timeline of your development.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1769282882364/23708959-7fc5-4337-bf94-1fe11933cea3.png align="center")

A SHA can be used to get information about the commit (commit object) by running `git cat-file -p <SHA>` (the first 6 initials of SHA are enough). The command gives:

* Tree id
    
* Parent Node ID (except for the first node)
    
* Author
    
* Committer
    
* Commit Message
    

## **The Three Objects**

Until now we said that Git takes periodic snapshots of the user’s codebase to track it but snapshots is a vague term, the technical terminology used is “**Blob**”. Git uses blobs to keep track of the codebase. To understand more about Blobs we need to address the three main objects of the Git, i.e.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1769283927217/bad8c9b4-2a04-409b-94b6-d3c79997c7b4.png align="center")

1. ### Commit Object :
    
    This object contains the metadata of each Commit like parent tree id, commit message, author, etc. It can be accessed with the command `git cat-file -p <Commit Hash>` . This object also contains the current Tree object which is used to access the Blob.
    
2. ### Tree Object :
    
    This object is found inside the Commit object and can be accessed by the command
    
    `git ls-tree <tree-id>`. It contains a unique Blob id for every file committed during that commit.
    
3. ### Blob Object :
    
    This is where the actual snapshot of the codebase is stored. The user can access the individual Blob files with the help of the blob objects with `git show <blob-id>`. Inside each individual blob are the entire content of the files at the moment. If the file hasn’t changed Git just points a blob object to the old one.
    

## **Understanding** `.git`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1769283144280/de38cc7d-232f-4944-8135-dd198c2b3c51.png align="center")

If we imagine our code development as a car ride journey from home (start) to destination (production) then `.git/` folder is the track connecting us to of our stops (the commits) we took on our journey, without .git the user wouldn’t able to access their past stops(commits) or use the alternate paths (branches) in their journey. To understand more about the working of Git we need to take a look inside the .git folder. The `.git/` folder contains :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1768848665885/e12ce97d-7fd5-4c9b-9de3-8aeeb7ada525.png align="center")

1. **HEAD** - It is a tiny file inside the folder that just contains the name of your current branch. It tells the user on which of the many alternate paths they are on.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1768850782720/acd7e753-92be-4690-9f6a-07c28e12f7fe.png align="center")
    
2. **Refs** - This folder contains all the branches and SHA’s of those branch. It is like a map that tells the user what are the path they have taken upto the current point.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1768851351070/a8f541f4-2c80-4302-b118-27ae8e2eb7b1.png align="center")
    
3. **Objects** - This is the the actual database of Git. It is where all the three objects (Commit, Tree, Blob) are stored in a compressed form.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1768851843495/5a154448-3d34-4163-9da6-cbe342ce3d4d.png align="center")
    

---

## **How Git Tracks Changes**

1. ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1769282963404/5c381cbf-3726-40be-8850-922b88b57a4e.png align="center")
    
    Git Add - This git command is used to add files to the staging area. Here you can either selectively send files to staging area or send all the modified files to staging area.
    
    `git add file1.txt // to add specific files to staging area`
    
    OR
    
    `git add . // to add all files to staging area`
    
2. Git Commit - This command is used to permanently commit files from the staging area to the main timeline.
    
    `git commit -m "Committing file1.txt"`
    

---
