Git Basics
Version control is not Google Drive.
What Is Version Control?
Imagine writing a novel and being able to rewind to any paragraph you ever wrote, on any day, and see exactly what changed, who changed it, and why. That is version control.
It is not Google Drive auto-save. Auto-save captures everything indiscriminately — every typo, every half-finished thought. Version control is intentional. You decide when to take a snapshot. You write a message explaining what that snapshot means. And every snapshot is permanent, reachable, and diffable against any other snapshot.
The tool that does this is called Git. It was created in 2005 by Linus Torvalds — the person who built the Linux kernel — because he needed something fast, distributed, and impossible to corrupt. He built it in about two weeks. It won. Virtually every software project on Earth uses Git now.
Git is not a backup system. It is a time machine you control. Every commit is a deliberate checkpoint that you chose to create, with a message explaining why.
The Three States
Git tracks your files in three states, and understanding these three states is the key to everything:
Working directory — This is your project folder right now. The files as they currently exist on disk. When you edit a file, the change lives here first.
Staging area — A holding zone where you prepare your next snapshot. You choose which changes to include. Maybe you edited five files but only want to commit three — you stage those three.
Repository — The permanent history. When you commit, everything in the staging area becomes a new snapshot in the repository. This snapshot is immutable. It exists forever (or until you explicitly tell Git to remove it, which is hard to do by accident).
The mental model is simple: you edit files (working directory) → you choose which changes to save (staging) → you save them with a message (commit to repository). Edit, stage, commit. That is the rhythm.
# The rhythm of Git:
# 1. Edit your files (working directory)
# 2. Stage the changes you want to save
git add index.html styles.css
# 3. Commit with a message explaining why
git commit -m "Add landing page layout and base styles"
The Core Commands
git init — Start tracking a project. Run this once in a project folder and Git begins watching. It creates a hidden .git folder where all the history lives.
git status — Your best friend. Shows what has changed, what is staged, what is not. Run this constantly. When in doubt, run git status.
git add — Stage changes. git add filename.js stages one file. git add . stages everything that changed. Be intentional about what you stage.
git commit -m "message" — Save a snapshot. The -m flag lets you write the message inline. Everything in the staging area becomes a permanent part of history.
git log — See the history. Shows every commit, who made it, when, and the message. Press q to exit the log view.
git diff — See what changed. Shows the exact lines that were added, removed, or modified since your last commit. Invaluable for reviewing your work before committing.
git init # Start tracking this folder
git status # What has changed?
git add . # Stage all changes
git commit -m "Initial commit" # Save the snapshot
git log # See the history
git diff # See uncommitted changes
Commit Messages
A commit message is a note to your future self (and anyone else who reads the history). The difference between a good message and a bad one is enormous.
Bad: "updated stuff." What stuff? Why? This tells you nothing six months from now.
Bad: "changed line 42 in App.jsx." This describes what Git already shows you in the diff. You are duplicating information.
Good: "Fix login timeout that logged users out after 30 seconds." This tells you what was wrong and what the fix accomplishes. Your future self can search for "login timeout" and find this commit instantly.
Good: "Add dark mode toggle to settings page." Clear, specific, describes intent.
The convention: start with a verb in imperative mood (Add, Fix, Update, Remove, Refactor). Keep it under 72 characters. If you need more detail, leave a blank line after the first line and write a longer description.
When Things Feel Scary
Here is the most important thing about Git: you almost cannot lose work. If you committed it, it is saved. Even if you make a mess, the history is still there.
If you are unsure what state things are in, run git status. It always tells you the truth.
If you made changes you want to undo before committing, git checkout -- filename restores a file to its last committed state.
If you committed something you did not mean to, git revert creates a new commit that undoes the previous one — without erasing history.
The only way to truly lose work is to delete uncommitted changes. So the rule is simple: commit early, commit often. A commit costs nothing. Losing an hour of work costs a lot.
When in doubt, commit. You can always reorganize history later. But you cannot recover work you never committed.
Your First Repository
Open your terminal. Create a project folder: mkdir git-practice && cd git-practice. Initialize Git: git init. You should see "Initialized empty Git repository." Create a file: touch README.md. Run git status — it shows README.md as untracked. Stage it: git add README.md. Run git status again — it is now staged. Commit: git commit -m "Initial commit with README". Run git log to see your first commit. Now open README.md in any text editor, add a line of text, save it. Run git diff — you can see exactly what changed. Stage and commit: git add . && git commit -m "Add description to README". Run git log — you now have two commits. You have a time machine.
Go Deeper
- Pro Git (free book) — The definitive Git reference. Chapters 1-3 cover everything a beginner needs.
- Oh Shit, Git!?! — A brilliant, profanity-laced guide to getting out of common Git messes. Bookmark this.
- GitHub Git Handbook — GitHub's concise introduction to Git concepts.
- Learn Git Branching — Interactive visual tutorial. Teaches branching with animated diagrams.