Why the terminal, and why start with the model
Most git tutorials hand you ten commands to memorize and you forget nine by Friday. This one is different: we teach the data model first - three zones, snapshots, and movable pointers - and let the commands fall out of it. By the end of six sessions you will run a real project the way engineers do: branch, PR, resolve conflicts, ship with CI. Every session works on one repo you own, driven entirely from the command line (or a Codespace if you cannot install locally).
Snapshots and pointers, not diffs 5 min live
The single misconception that makes git confusing: people think it stores changes. It does not. Every commit is a full snapshot of your project, and git is ruthlessly efficient about not duplicating unchanged files. A branch is not a copy - it is a movable pointer to one snapshot. HEAD is the pointer that says "you are here".
LiveCommit = snapshot, branch = pointer, HEAD = you3 min▶
- Commit - a complete snapshot of every tracked file at one moment, with a unique hash (a3f9...), an author, a time, a message, and a link to its parent. The chain of parents IS your history.
- Branch - a named pointer to one commit.
mainandfeatureabove are just labels on snapshots. Creating a branch writes one 40-character file. That is why engineers branch constantly. - HEAD - the pointer to the branch (or commit) you are currently on. "Checking out" a branch moves HEAD. Almost every "wait, where am I?" moment is a HEAD question.
Linus Torvalds wrote git in 2005 in about ten days to manage the Linux kernel after the project lost access to its proprietary tool. The snapshot-and-pointer design is exactly why it scales to a project with 1,000+ contributors and a million commits: reading history is following a chain, and branching is free.
Self-studyThe three zones: working tree, staging, repository3 min read▶
Every file lives in one of three zones, and every basic command just moves files between them. This is the model that makes add and commit stop feeling arbitrary.
| Zone | What it is | Command to enter it |
|---|---|---|
| Working tree | your actual files on disk, edited freely | (you just edit) |
| Staging area (index) | the guest list for the next commit | git add |
| Repository | permanent snapshots, the history | git commit |
Staging feels like a pointless extra step for one week, then you realize it lets you commit part of your work with a clean message while leaving the rest in progress. It is a feature, not a toll.
Install, configure, or open a Codespace 5 min live
Two paths to a terminal with git. Local install is the long-term home; a Codespace is a full browser-based dev environment (git pre-installed) that gets anyone unblocked in 60 seconds - use it if install is fighting you.
LiveThe one-time setup every builder does once3 min▶
Check whether git is already there (macOS and most Linux ship it):
If missing: macOS brew install git, Windows install Git for Windows (gives you Git Bash), Linux sudo apt install git. Then set your identity once - it stamps every commit you will ever make:
. (period) or click Code → Codespaces → Create. You get VS Code in the browser with git and gh already configured and authenticated. Nothing to install. This is also how you follow along on a locked-down work laptop.
Self-studyThe gh CLI: GitHub in your terminal2 min read▶
git talks to repositories; gh (GitHub CLI) talks to GitHub - PRs, issues, releases - without leaving the terminal. You will lean on it from Session 3. Install and log in once:
Codespaces come with gh pre-authenticated, so you can skip this there.
init, status, add, commit, log 5 min live
Five commands take a folder from "just files" to "a repository with history". Watch which zone each one touches - that is the whole point of doing it slowly once.
LiveReading status and log like a local3 min▶
git statusis your compass. Run it constantly. It tells you your branch, what is staged (green), what is modified but unstaged (red), and what is untracked. When lost, status first.git addis staging, not saving. It copies the current state of a file to the staging area. Edit after adding, and you must add again - the stage holds a snapshot, not a live link.git commit -mwrites the snapshot. Message style: imperative mood, under ~50 chars for the summary ("Add expense parser", not "added stuff"). Future-you greps these.git diffvsgit diff --staged. The first shows unstaged changes (working vs stage); the second shows staged changes (stage vs last commit). Two questions, two commands.
Good commit history is a debugging superpower. When production breaks, git log and git bisect let a team binary-search 500 commits to find the exact snapshot that introduced a bug in minutes. That is only possible because each commit is a coherent, message-labeled snapshot - which starts with the habits you build today.
Self-studyConnecting to GitHub: remote, push2 min read▶
Your commits are local until you push them to a remote (GitHub). The fastest path uses gh to create the repo and wire it up in one step:
Under the hood that sets origin (the remote's nickname) and runs git push -u origin main. Session 2 makes push/pull a daily reflex.
Get a working git ★ 6 min · everyone sets up
Open a terminal (or press . on any GitHub repo for a Codespace). Run git --version - confirm you have one, or install per Part 2.
Set your identity: the three git config --global lines from Part 2. Verify with git config --global --list.
If you will use gh locally, run gh auth login now (skip in a Codespace - already done).
Make a home for today: mkdir my-project && cd my-project. This folder becomes your running artifact for all six sessions.
Make your first three commits ★ 9 min · everyone types
git init, then create a README: echo "# My Project" > README.md. Run git status and read it aloud - README is untracked (red).
git add README.md, git status again - now it is staged (green). Notice the file moved zones without changing on disk.
git commit -m "Add project README". Then add two more small files (a .gitignore, a notes.md) and commit each with its own clear message. Three snapshots.
git log --oneline. You just built a history chain by hand. Read the hashes - each is a snapshot you can return to.
gh repo create my-project --public --source . --push and your local history is on GitHub. We make this routine in Session 2.
Feel the model in the graph ★ 7 min · everyone clicks
Before you branch for real in Session 3, build the intuition here. Each button is the command it names - watch commits become snapshots and branches become pointers.
This is not a toy rendering - it is the same graph git log --graph --oneline --all draws in your terminal, and the same one GitHub's network view shows. Learn to read it here and you can read any project's history at a glance.
This week ◐ 25 min total
- Commit daily for five days in your my-project repo, even trivially. Goal: make
status → add → commitmuscle memory before Session 2 turns it into a loop with push. - Practice reading: run
git log --graph --oneline --alland confirm it matches the mental model from the playground. - Read the self-study cards: the three zones, the gh CLI, remotes and push.
- Optional deep end: the official Introduction to Git Skills exercise (github.com/skills/introduction-to-git) - hands-on CLI in a real repo, reinforces today.
Three questions before you go 🎯 ◐ 90 seconds
1 · What does a commit actually store?
Git is a snapshot store, not a diff store. It shows you diffs when asked, but each commit is a complete picture - which is why branching and history reading are so fast.
2 · You edited a file, ran git add, then edited it again. What is in the next commit if you commit now?
Staging captures the file's state at add-time. The second edit sits in the working tree until you add again. This is the three-zone model doing exactly what it says.
3 · What is a branch, mechanically?
A branch is a 40-character file naming one commit. That is why engineers make them freely - Session 3 does exactly that.
Official GitHub Skills coverage
This track maps to GitHub's own free CLI-based Skills exercises. Each session states what is covered here and what the official exercise adds.
Session 1 cheat sheet · pin this
git add → staging → git commit → repository.git config --global user.name / user.email / init.defaultBranch main.git init · status · add · commit -m · log --oneline.git status first, always. It names your branch and every file's zone.. on any repo for a Codespace: git + gh pre-configured in the browser.