Git
Git Essentials: Version Control That Finally Makes Sense
The mental model behind Git — repository, staging area, branches — plus the daily command loop, practiced on a real repository you build as you read.
Tutorial overview
What you will learn
- Explain the three zones of Git: working directory
- staging area
- repository
- Run the daily loop — status
- add
- commit — without thinking
- Create
- merge
- and delete branches confidently
- Connect a local repository to a remote and push/pull
- Undo mistakes at each stage without fear
By the end, you will have
- A practice repository with real history
- a merged branch
- and an undone mistake
- A daily Git routine you can run on autopilot
- The vocabulary to read Git documentation and error messages
Introduction
Git tracks every version of your work, lets you experiment without fear, and is the collaboration backbone of essentially all modern software. It is also famously confusing to learn from error messages alone — because Git only makes sense once you hold its mental model, and most people are handed commands before the model.
This tutorial does it in the right order: model first, commands second, practiced on a real repository you'll build as you go. If you're returning after time away, the model is the part that comes back — skim Steps 1–2 and the muscle memory follows.
What you will build or practice
A real repository with meaningful history: several commits, a branch you create and merge, a remote-ready setup, and — most importantly — a mistake you make on purpose and then undo. Fear of breaking things is the main thing that keeps people from using Git well; we remove it deliberately.
Before you begin
Install Git from git-scm.com (every OS has an installer; on Ubuntu/WSL it's sudo apt install git). Then introduce yourself — Git stamps every commit with this identity:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
Key concept
Git moves your work through three zones.
- The working directory — your files as they are right now, on disk.
- The staging area — a loading dock where you assemble the next snapshot.
git addputs changes here. - The repository — the permanent history of snapshots.
git commitseals whatever is on the loading dock into it.
Almost every beginner confusion dissolves against this picture. "Why didn't my change get committed?" — it was never staged. "What does git status show?" — the difference between the three zones. A commit is just a sealed snapshot with a message, an author, and a pointer to its parent — history is a chain of them. A branch is nothing but a movable label pointing at one commit. That's the whole model.
Step 1: Make a repository and read git status
mkdir git-practice && cd git-practice
git init
git status
git init creates a hidden .git folder — that is the repository; delete it and the folder becomes ordinary files again. git status is Git's dashboard and your most-typed command: it always tells you what zone everything is in and usually suggests the next command. When in doubt, run it.
Step 2: The daily loop — status, add, commit
Create a file and walk it through the zones:
echo "# Recipe collection" > README.md
git status # "untracked" — Git sees it, isn't tracking it
git add README.md # onto the loading dock
git status # "changes to be committed"
git commit -m "Add project readme"
git status # clean — all three zones agree
Now change the file and go around again:
echo "## Pasta" >> README.md
git add README.md
git commit -m "Start the pasta section"
git log --oneline # your history, one line per commit
That loop — edit, add, commit with a message that says why — is 80% of daily Git. Two habits worth forming now: run git diff before staging to see exactly what changed, and keep commits small enough that the message can be honest.
Step 3: Branches — cheap experiments
A branch lets you work on something risky while the main line stays untouched:
git switch -c desserts # create a branch and move onto it
echo "## Tiramisu" >> README.md
git commit -am "Add tiramisu" # -a stages tracked-file changes in one go
git switch main # look: README has no tiramisu here
git switch desserts # and now it does again
Nothing was copied — a branch is a label, so creating one is instant and free. This is Git's superpower: every idea, fix, or experiment gets its own branch, and abandoning a bad idea is just deleting a label.
Merge it back when it's ready:
git switch main
git merge desserts # bring the branch's commits into main
git branch -d desserts # delete the label; the commits remain
If both branches changed the same lines, Git stops and asks you to resolve a conflict — it marks the competing versions in the file with <<<<<<< markers, you edit the file to keep what's right, then git add and git commit. Conflicts feel alarming and are actually just Git refusing to guess.
Step 4: Remotes — your repository, elsewhere
Everything so far lives on your machine. A remote is a copy of the repository somewhere else — GitHub, GitLab, Bitbucket — used for backup and collaboration:
git remote add origin <url-from-your-hosting-service>
git push -u origin main # first push; -u links the branches
git push # every push after that
git pull # fetch others' commits and merge them in
origin is just the conventional nickname for your main remote. The rhythm with others is: pull before you start, work in small commits, push when tests pass. One naming note: git init still names the first branch master by default, while the big hosting services use main — git config --global init.defaultBranch main makes your local default match.
Step 5: Undo — the fear removal step
Make a mistake on purpose:
echo "TERRIBLE IDEA" >> README.md
Now undo it at each zone, matching the command to where the change lives:
- Not staged yet:
git restore README.md— the file snaps back to the last commit. (The change is gone for good, so this is the one to double-check.) - Staged but not committed:
git restore --staged README.md— pulls it off the loading dock; the edit stays in the file. - Committed:
git revert HEAD— creates a new commit that undoes the last one. History stays intact, which is why this is the safe choice on anything already pushed. - Committed the wrong message a second ago:
git commit --amend -m "Better message"— fine locally, avoid on pushed commits.
The deeper reassurance: anything ever committed is very hard to truly lose. git reflog lists everywhere your branches have pointed, even "deleted" commits — it has rescued every developer you admire at least once.
Practice exercise
- The task: in a fresh folder, create a repo for a fictional blog. Make three commits on
main(add a post, edit it, add a second post). Create a branchredesign, change something, merge it back, delete the branch. Then revert the merge commit. - Expected output:
git log --onelineshows the whole story, ending with a revert commit. - One hint: after the merge,
git logshows the merge commit at the top —git revert HEADmay ask which parent to keep;git revert -m 1 HEADkeeps main's side. - Stretch goal: create a free account on a hosting service, add it as a remote, and push. Your practice repo is now backed up off your machine.
Common mistakes
- Editing and wondering why commits are empty. You skipped
add. The loading dock is never optional —git statuswould have told you. - Giant commits with messages like "stuff" or "fixes". A commit should be one change with a message stating why. Future-you reading
git logis the customer. - Working directly on main for everything. Branches are free. The habit of branching per task is what makes experiments — and collaboration — painless.
- Reaching for deletion when Git gets confusing. Deleting the folder and re-cloning "works," but every such moment is a missed lesson;
git statusplus the undo table above resolves nearly all of them. - Committing secrets. Passwords, API keys, and
.envfiles must never enter history — once pushed, treat a leaked key as compromised and rotate it. A.gitignorefile (list filenames/patterns, one per line) keeps them out; add it in your first commit.
Check your understanding
- Name the three zones and the two commands that move work between them.
- Why is
git revertsafer than deleting commits on a branch others have pulled? - Your teammate says "my change vanished after I ran
git restore." What happened, and which zone was the change in?
Key takeaways
- Git is three zones: working directory → (
add) → staging area → (commit) → repository. git statusis the dashboard; when confused, run it and read what it says.- Branches are movable labels — instant, free, and the right home for every experiment.
- Remotes add backup and collaboration:
pullbefore working,pushwhen green. - Every zone has an undo, and committed work is almost impossible to truly lose. Fear is optional.
Next steps
Keep the Git Commands Cheat Sheet open until the loop is automatic — it compresses this tutorial and adds the next tier (stash, log archaeology, tag). Then make it real: spin up a project starter, git init, and build the history habit on an actual project.
Related resources
- Git Commands Cheat Sheet — the quick-reference version
- Linux Command Line Essentials — the terminal fluency this builds on
- Project Starters — new projects to practice the workflow on
Newsletter or next lesson
The developer-tools lane is growing — browse all tutorials for the current set, one clear step at a time.