Git from the Terminal

Lesson 4 of 5

Behind the Curtain

Concept:

The .git folder is Git's entire database. HEAD is a text file pointing to your current branch. Each branch is a file in .git/refs/heads/ containing a 40-character commit hash. The objects/ folder stores every version of every file ever committed. Delete .git and all history vanishes β€” your files stay but Git is gone. The .gitignore file tells Git which files to never track: build artifacts, IDE configs, secrets, logs.
Socrates: We have spoken of branches, commits, and the four areas. But all this time, I have been asking you to trust me. Let us now verify. Where do you think Git stores everything?
Student: Somewhere on my computer? In a database?
Socrates: In a hidden folder called .git, sitting right inside your project. No cloud service, no background process. Just files in a folder. Would you like to look inside?
Student: We can just... open it?
Socrates: Of course! There is no magic. HEAD is a text file β€” open it and you will see which branch you are on. Each branch in refs/heads/ is a file containing a 40-character hash. The objects/ folder holds every version of every file ever committed.
Student: So when we said 'a branch is just a pointer'...
Socrates: We meant it literally. A file with a hash inside. Delete that file and the branch is gone. Delete the entire .git folder and all history vanishes β€” though your working files remain.
Student: That's both elegant and terrifying.
Socrates: Which is why we also need .gitignore β€” a file that tells Git what to never track. Build artifacts, IDE settings, log files, and above all, secrets. A .env file committed to GitHub is visible to anyone who can see the repository.
Student: I should create .gitignore before my first commit?
Socrates: Always. Retroactively ignoring a file that is already tracked requires extra work β€” 'git rm --cached'. Prevention is cleaner than cure. Now β€” read the HEAD file yourself. See with your own eyes what your GUI never showed you.
Example Code:
    my-project/
    β”œβ”€β”€ src/
    β”‚   └── App.java
    β”œβ”€β”€ .gitignore          ← files Git should ignore
    └── .git/               ← Git's entire database
        β”œβ”€β”€ HEAD             ← text file: 'ref: refs/heads/main'
        β”œβ”€β”€ objects/         ← every version of every file (hashed)
        β”œβ”€β”€ refs/heads/      ← branches (just files with commit hashes)
        β”‚   └── main         ← contains: a3f9d12c8b...
        └── config           ← repo settings

    Example .gitignore:
    target/           # build output
    .idea/            # IDE files
    *.log             # log files
    .env              # secrets β€” NEVER commit these

Your Assignment

Look inside Git's brain: read the contents of the HEAD file with 'cat .git/HEAD' to see which branch you're on.

Git Console
git>