Fundamentals 9 min read

Understanding the .git Directory Structure and Its Components

The hidden .git folder stores all repository data—including configuration, branch references, commit objects, logs, the staging index, and executable hooks—organized into subdirectories such as config, objects, refs, logs, info, hooks, and index, enabling Git to track history, manage branches, and automate workflows.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Understanding the .git Directory Structure and Its Components

Every Git repository contains a hidden .git directory that stores the repository's internal data such as branches, commits, configuration, and logs.

The directory layout is relatively simple but powerful. Below is the full structure of a typical .git folder:

.git
|----config
|----objects
|   |---0d
|   |   |---0d218acc58d857329cde3778d7429037079627
|   |   |---60436b1116e54b3ed9a4b9fec1f2f9916a73ca
|   |---59
|   |   |----a10af7aa35f521b9a41569785d4481850192e3
|   |---92
|   |   |---5f4810ed4da9873771f14f2ca1ab97db81283a
|   |   |---6c85f1ad90849159b2c616a9744ba62abe8f6a
|   |   |----c359f0b8d09e2fc137c865043d4f6951989cdd
|----HEAD
|----info
|   |----exclude
|----logs
|   |----HEAD
|   |----refs
|       |----heads
|       |   |----main
|       |----remotes
|           |----origin
|               |----main
|----description
|----hooks
|   |----commit-msg.sample
|   |----pre-rebase.sample
|   |----pre-commit.sample
|   |----applypatch-msg.sample
|   |----fsmonitor-watchman.sample
|   |----pre-receive.sample
|   |----prepare-commit-msg.sample
|   |----post-update.sample
|   |----pre-merge-commit.sample
|   |----pre-applypatch.sample
|   |----pre-push.sample
|   |----update.sample
|   |----push-to-checkout.sample
|----refs
|   |----heads
|   |   |----main
|   |----tags
|   |----remotes
|       |----origin
|           |----main
|----index
|----COMMIT_EDITMSG

HEAD (Current Branch)

The HEAD file records the name of the branch currently checked out. Its content looks like: ref: refs/heads/main or for another branch: ref: refs/heads/dev refs

Under .git/refs there are three sub‑directories— heads, tags, and remotes —that store references to the latest commit IDs for local branches, tags, and remote branches respectively.

|----refs
|   |----heads
|   |   |----main
|   |----tags
|   |----remotes
|       |----origin
|           |----main

.git/refs/heads

Each local branch has a file like .git/refs/heads/main containing the SHA‑1 of the latest commit on that branch, e.g.: 2ddc65b74a186f4332d7b218be0f18dd404c82ef.git/refs/remotes

This directory mirrors the state of remote branches, allowing Git to track changes on the remote repository.

.git/refs/tags

When you create a tag, a file is added here to point to the commit the tag references.

.git/refs/stash

If you use git stash, the stash information is stored in this directory.

Typical use cases for git stash include temporarily switching branches without committing unfinished work, or saving local changes while pulling upstream updates.

Commit Objects (.git/objects)

References in refs ultimately point to files in .git/objects. A commit object is stored as a two‑level path where the first two hex digits form a directory and the remaining characters form the filename, e.g.: .git/objects/2d/dc65b74a186f4332d7b218be0f18dd404c82ef You can inspect a commit with: git cat-file -p 2ddc65b74a186f4332d7b218be0f18dd404c82ef This displays the commit tree, author, committer, and message.

Similarly, you can view the tree object: git cat-file -p f8803d7d049edbbc981da732b855419d039f79ff and any blob (file) object with the same command.

Logs (.git/logs)

The .git/logs directory records every update to refs, including the previous and new SHA‑1, author, timestamp, and commit message.

|----logs
|   |----HEAD
|   |----refs
|       |----heads
|           |----main
|       |----remotes
|           |----origin
|               |----main

config

The repository‑specific configuration resides in .git/config. It defines core settings, remote URLs, and branch merge information.

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
    ignorecase = true
    precomposeunicode = true
[remote "origin"]
    url = https://github.com/xxxx/xxxx-blog.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main

index (Staging Area)

The .git/index file stores the snapshot of files that have been staged with git add. When git commit runs, the index content becomes a new commit.

hooks

Git hooks are executable scripts located in .git/hooks that run at specific points in the workflow, such as pre-commit, post-commit, or pre-push, allowing custom automation.

Understanding these internal components helps developers troubleshoot, customize workflows, and gain deeper insight into how Git manages version history.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backend DevelopmentConfigurationDevOpsGitVersion ControlRepository Structure
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.