Skip to main content

Command Palette

Search for a command to run...

Shug Opens the .git Folder

the one where shug becomes git master

Updated
β€’11 min read
Shug Opens the .git Folder
S

Frontend React Developer experimenting technology in a creative wayπŸ‘¨πŸ»β€πŸ’»βœ¨ | Aspiring EntreprenuerπŸ‘¨πŸ»β€πŸ’ΌπŸ“ˆ

the forbidden folder

shug has been using git for weeks.

git add. git commit. git push.

commands work. project is safe.

but never looked inside .git folder.

uncle mentioned it once: "that's where git keeps everything"

today is the day.

enable hidden files

shug goes to folder settings.

clicks "show hidden files"

waits.

.git folder appears.

shug stares at it.

double clicks.

folder opens.

dramatic music plays in head 🎡

what lives inside

.git/
β”œβ”€β”€ HEAD
β”œβ”€β”€ config
β”œβ”€β”€ objects/
β”œβ”€β”€ refs/
β”‚   β”œβ”€β”€ heads/
β”‚   └── tags/
└── ...more stuff

shug blinks.

weird file names. folders with cryptic names.

no .html. no .css. no normal files.

this is git's brain.

the objects folder (memory vault)

.git/objects/

shug clicks into it.

hundreds of folders.

each has 2-character names: a1/, f3/, 9e/...

inside each folder: more weird files with long names.

no file extensions.

shug tries to open one in text editor.

οΏ½οΏ½xοΏ½KοΏ½οΏ½OR04fοΏ½IοΏ½οΏ½QοΏ½οΏ½οΏ½οΏ½+οΏ½...

gibberish.

closes it quickly.

(feels like opened something not meant for humans)

uncle's voice in head: "objects folder stores everything"

okay but... everything as what?

shug googles: "git objects folder"

article says: "each file is a git object with SHA-1 hash"

shug: "what's a shaw-one"

more googling.

oh. it's SHA-1. like S-H-A.

hash = fingerprint for data.

same data = same hash.

different data = different hash.

so this folder stores:

  • every file shug ever committed

  • every commit message

  • every version of every file

all compressed into these weird binary files.

shug stares.

this is git's actual memory.

the brain.

the vault.

everything is here.

nothing is ever truly deleted.

shug feels weird about it.

my entire project history is in this one folder?

checks folder size: 4.2 MB

project is 50 MB.

how?

git compression magic.

(uncle will explain later)

for now shug just knows:

.git/objects/ = where git remembers everything.

touch this folder = break git.

respect this folder = git respects you.

shug closes it gently.

like closing someone's diary.

reading a commit object

okay but can shug actually read these things?

googles again: "how to read git objects"

finds command: git cat-file

uncle mentioned this once.

time to try.

first: get a commit hash.

git log --oneline

output:

a1b2c3d updated heading
e4f5g6h fixed typo
7h8i9j0 initial commit

okay. a1b2c3d is latest commit.

now the scary command:

git cat-file -p a1b2c3d

shug hits enter.

holds breath.

output:

tree 4f8e9a1
parent e4f5g6h
author shug <shug@email.com>
committer shug <shug@email.com>
date: Mon Jan 8 14:23:11 2024

updated heading

shug stares.

it worked?

it just... showed the commit?

reads it again.

commit has structure:

  • tree 4f8e9a1 β†’ project snapshot at this moment

  • parent e4f5g6h β†’ previous commit (the one before this)

  • author β†’ who made it (me)

  • committer β†’ who committed it (also me)

  • date β†’ when

  • updated heading β†’ commit message (why)

shug tries something.

what if checks the parent commit?

git cat-file -p e4f5g6h

output:

tree 2c3d4e5
parent 7h8i9j0
author shug <shug@email.com>

fixed typo

it has a parent too.

which also has a parent.

wait.

it's a chain.

shug's brain clicks.

every commit points to its parent.

git follows these pointers backward.

that's how git log works.

that's how history exists.

mind blown. 🀯

sits back in chair.

stares at ceiling.

git isn't magic.

it's just... linked data.

like a playlist where each song remembers the previous song.

tries one more thing:

git cat-file -p 4f8e9a1

(that's the tree hash from first commit)

output:

100644 blob 8ab3f21    index.html
100644 blob f39d8e2    style.css
040000 tree a84d9c1    images/

the tree shows files in that commit.

each file has its own hash (blob).

shug checks a blob:

git cat-file -p 8ab3f21

output:

<!DOCTYPE html>
<html>
  <head>
    <title>shug's project</title>

it's the actual file content.

shug leans back.

closes laptop.

needs a moment.

the whole system just made sense:

  1. you commit β†’ git creates snapshot

  2. snapshot = tree object listing all files

  3. each file = blob object with content

  4. commit points to tree + parent commit

  5. git walks these links for history

opens laptop again.

one more test.

creates new file. commits it.

checks .git/objects/ folder.

new folders appeared.

new hashes.

for new commit. new tree. new blob.

everything is stored.

everything is linked.

git is just a graph database.

shug messages uncle:

"i get it now"

uncle: "get what"

"commits are linked lists"

uncle: "πŸŽ‰"

raj messages same time:

"git push not working again"

shug screenshots the git cat-file output.

sends to raj.

raj: "what is this"

shug: "your future"

leaves him on read.

some people aren't ready.

commits are linked (the chain)

shug draws this on paper:

commit 01 ← commit 02 ← commit 03
                          ↑
                        HEAD

each arrow is a parent pointer.

git walks backward through parents.

this creates complete history.

shug finally understands git log.

it's not magic.

git starts at HEAD.

reads current commit.

checks parent. reads that.

checks parent. reads that.

keeps going until no more parents.

that's the log.

simple.

HEAD: your position marker

.git/HEAD

shug opens this file in text editor:

ref: refs/heads/main

one line. that's it.

HEAD points to current branch.

branch points to latest commit.

shug thinks: "so HEAD is like... my cursor in history?"

yes. exactly that.

HEAD = "you are here" marker

make new commit β†’ HEAD moves forward

checkout old commit β†’ HEAD moves backward

tries something:

git checkout e4f5g6h

(checking out old commit directly)

warning message appears:

You are in 'detached HEAD' state...

shug panics.

googles "detached head git"

oh. HEAD just moved off the branch.

now points directly to commit instead of branch name.

not broken. just... floating.

git checkout main

HEAD reattaches.

crisis averted.

the bug scenario (shug's nightmare returns)

remember episode 1?

shug committed bug. broke entire project.

had to rewrite everything from memory.

never again.

scenario:

shug commits bug in commit 03.

realizes 2 commits later at commit 05.

panic mode activated.

but wait.

shug knows git now.

option 1: revert (the safe way)

git revert 03

shug tries it.

git opens editor.

asks for commit message.

shug types: "reverting the bug commit"

saves.

done.

checks git log:

01 ← 02 ← 03 ← 04 ← 05 ← 06 (revert of 03)
                              ↑
                            HEAD

commit 03 still exists in history.

but commit 06 undoes its changes.

bug is gone.

history is preserved.

team can see what happened.

safe. reversible. professional.

option 2: reset (the dangerous way)

shug reads about another option.

git reset --hard

"use with caution" every article says.

shug creates test branch to try it.

git reset --hard 02

poof.

commits 03, 04, 05 disappear from git log.

01 ← 02
      ↑
    HEAD

(03, 04, 05 are gone)

checks working directory.

files reverted to commit 02 state.

all changes after that: deleted.

shug's heart races.

this is powerful.

but dangerous.

what if already pushed to team?

now their history has commits that yours doesn't.

merge conflicts from hell.

quickly undoes test:

git reflog

(shows all HEAD movements, even deleted commits)

finds deleted commit hash.

git reset --hard a1b2c3d

commits are back.

breathes again.

lesson learned:

git revert = safe for shared branches

git reset --hard = only for local mistakes

never reset shared history.

shug writes this on sticky note.

sticks to monitor.

branches revealed (biggest surprise)

shug always thought branch = copy of code.

like:

  • main folder with all files

  • feature folder with all files copied

heavy. slow. duplicate everything.

wrong.

goes to:

.git/refs/heads/main

opens file.

a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0

one line.

just a commit hash.

that's it.

branch = pointer to commit.

nothing more.

no copied files.

no duplicate data.

just a named pointer.

shug stands up.

sits back down.

opens feature branch file:

.git/refs/heads/feature

inside:

x1y2z3a4b5c6d7e8f9g0h1i2j3k4l5m6n7o8p9q0

different hash.

different pointer.

that's the only difference between branches.

years of confusion solved in one folder.

creating branch (what really happens)

shug tests this theory.

git checkout -b test-branch

output:

Switched to a new branch 'test-branch'

checks .git/refs/heads/:

new file appeared: test-branch

inside: same commit hash as main.

because created from main.

both point to same commit initially.

makes one commit on test-branch.

checks file again:

hash changed.

now points to new commit.

main still points to old commit.

      main
       ↓
01 ← 02
       β†–
         03 ← test-branch

no duplication.

no copying.

just pointers moving.

brilliant.

shug deletes test-branch:

git branch -d test-branch

checks .git/refs/heads/:

file is gone.

that's all deleting a branch does.

removes the pointer file.

commit 03 still exists in objects folder.

just not pointed to by any branch.

(will be garbage collected eventually)

the snapshot insight

shug reads more about git internals.

article says something weird:

"git doesn't track changes. it tracks snapshots."

reads that again.

what?

every commit = complete picture of project.

not "changed line 12 in file.css"

but "here's entire project at this moment"

shug tests:

changes one line in style.css.

commits.

git show HEAD

output shows:

- color: blue;
+ color: red;

but internally?

git stored entire new version of style.css.

compared both versions.

showed difference.

why do this?

because comparing two snapshots is fast.

tracking individual changes is slow and complex.

snapshots are simple.

git optimizes storage with compression.

but concept is: full snapshots.

shug's mental model updates:

commits aren't deltas.

commits are photographs.

git album of project over time.

config file (repository settings)

.git/config

shug opens it:

[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
[remote "origin"]
    url = https://github.com/shug/project.git
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
    remote = origin
    merge = refs/heads/main

readable. editable. just text.

this stores:

  • remote repository url (github)

  • branch tracking info

  • user preferences

  • repository settings

can edit manually.

or use commands:

git config user.name "shug"
git config user.email "shug@email.com"

both work.

config file updates either way.

shug changes email:

git config user.email "shug@newmail.com"

checks config file:

[user]
    email = shug@newmail.com

appeared at bottom.

all git config lives here.

no hidden database.

just text file.

everything connects

shug draws final mental map on whiteboard:

1. working directory β†’ where you edit files

2. staging area β†’ temporary selection (git add)

3. repository β†’ permanent history (git commit)

4. objects folder β†’ where data actually lives

5. HEAD β†’ current position marker

6. branches β†’ named pointers to commits

7. commits β†’ linked snapshots with parent pointers

arrows between everything.

the system makes sense now.

not magic.

just clever file organization.

the transformation

shug opens old notes from episode 1.

before:

  • copied commands from stackoverflow

  • git was black box

  • feared every operation

  • "what if i break something"

  • "why didn't it work"

  • panic when errors appeared

after:

  • understands what commands do

  • can predict git behavior

  • reads error messages and knows why

  • "oh, HEAD is detached, just checkout main"

  • "revert instead of reset for shared branch"

  • confidence in daily workflow

the difference isn't commands memorized.

the difference is mental model.

shug knows what's happening inside .git.

commands make sense now.

shug's new powers

now shug can:

  • recover deleted code βœ… (git reflog)

  • track who changed what βœ… (git log)

  • rollback to any point βœ… (git revert or git reset)

  • work on features safely βœ… (branches are just pointers)

  • collaborate without chaos βœ… (understanding merge/push)

  • sleep peacefully βœ… (everything is stored)

the pendrive trauma is healed.

final realization

shug closes laptop.

leans back.

thinks about the journey.

git exists because humans:

  • forget things

  • make mistakes

  • need history

  • collaborate badly

  • overwrite each other's work

  • lose files

git remembers so you don't have to.

.git folder is safety net.

commits are checkpoints.

branches are parallel universes.

HEAD is your position.

shug respects git now. 🧠✨

not just tool.

but philosophy.

version everything.

commit often.

history is freedom.

what shug learned throughout the journey

episode 1: the problem

  • collaboration without version control = chaos

  • pendrives and email don't scale

  • manually tracking versions fails

  • humans need automatic memory

  • git solves this

episode 2: the basics

  • git tracks changes locally

  • three-stage workflow: edit β†’ stage β†’ commit

  • basic commands for daily work

  • github for remote backup

  • never lose work again

episode 3: the internals

  • everything lives in .git folder

  • objects folder stores all data

  • commits are linked snapshots

  • branches are just pointers

  • HEAD tracks position

  • git is simple system, not magic

three weeks later

shug helps coworker with git issue.

coworker: "git says detached HEAD, what do i do?"

shug: "checkout your branch name"

coworker: "how did you know?"

shug shrugs: "just know how HEAD works"

explains pointers and commits.

coworker stares.

"you're really good at this"

shug thinks back to episode 1.

remembers crying over lost pendrive.

remembers raj's smug face.

remembers uncle's patience.

look at me now.

the end

raj texts: "can you help with my git"

shug: "did you read the docs?"

raj: "too long"

shug: "then suffer"

some people never learn.

but shug did.

and now?

git is second nature.

.git folder is old friend.

commits flow naturally.

shug conquered git.

(and raj? still emails zip files. 😀)

to be continued?

shug still has questions:

  • merge conflicts (when history diverges)

  • rebasing (rewriting history cleanly)

  • advanced workflows (git flow, trunk-based)

but that's for another day.

for now, fundamentals are solid.

and that's enough.

shug will sleep happily now after sipping his hot cup of chai.