Git — Your Time Machine
- Explain the three areas — working directory, staging area, history — and move changes between them
- Run the core cycle fluently: status, add, commit, log, diff
- Write commit messages that explain why, and stage related changes together
- Ignore generated files with .gitignore
- Undo safely: restore a file, unstage a change, and explain what reset does
| Spaced-rep warm-up: Week 1 misses + due cards | 10 min |
| Concept study: ELI5 + tech, watch the git-graph visualizer | 20 min |
| Guided: first repo, the cycle, ignore & undo drills | 50 min |
| Practice: commit surgery | 15 min |
| Project: the journey under version control | 15 min |
| Quiz + flashcards | 10 min |
Builds on: Day 6 — Terminal fluency · Day 7 — The task tracker (today's repo)
Every video game worth playing has save points. Before the boss fight, you save; if it goes badly, you reload and nothing is truly lost. Now recall Saturday's fear: you're about to refactor a working program, and the only "undo" is Ctrl+Z until your wrist hurts — and none at all once the editor closes. Git gives your project save points. A commit is a snapshot of your entire project at one moment, stamped with a message, an author, and a timestamp, kept forever in the project's history. Break everything an hour later? Reload the save.
Git's one genuinely odd idea is the staging area. You don't snapshot everything that changed — you first *frame the shot*. git add places chosen changes onto the tripod; git commit clicks the shutter. That's what lets one messy afternoon become three tidy save points: "fix the id bug", "add due dates", "update README" — each a story someone can follow later. The someone is usually you, in three weeks, at midnight, hunting for what broke.
Git is the closest thing software has to a universal requirement: every job, every team, every open-source project. From today, everything you build lives in git — by Day 20 you'll collaborate through GitHub, by Day 141 your commits will trigger eval gates in CI, and on Day 152 a push to main will deploy a real service. For AI engineers specifically, git is how prompts and eval sets get versioned and reviewed (Day 109) — "which prompt version caused this regression?" is answered by git log or not at all. And your GitHub history becomes your portfolio: hiring managers really do read it.
Save points for your work — commits form a graph
step 1 / 6Each commit is a full snapshot of your project plus a pointer to its parent. c2 knows it came after c1 — history is a chain, not a pile of zips.
Guided practice
First repository — snapshot the tracker
15 min- One-time setup: git config --global user.name "Your Name" and git config --global user.email "you@example.com" (use your real email — Day 20 ties it to GitHub).
- cd into week-01/tracker/ and run git init. Run ls -la and find the .git folder — that IS the repository; delete it and the history is gone (don't).
- Run git status and read every line out loud. tracker.py and tasks.json are "untracked" — git sees them but has never snapshotted them.
- Stage and shoot: git add tracker.py, then git status again (notice tasks.json stayed untracked — you chose the frame). Commit: git commit -m "Add task tracker CLI from Week 1 checkpoint".
- Run git log and read your first commit: hash, author, date, message. That 40-character hash is the save point's name forever.
The cycle in anger — edit, diff, stage, commit
20 min- Make a real change: in tracker.py, improve one user-facing message (e.g. the unknown-command reply). Run git status (modified), then git diff — read the minus/plus lines; this is your change as git sees it.
- Stage it, then run git diff (empty now) versus git diff --staged (your change). Write the rule in your journal: diff shows working-vs-staged, diff --staged shows staged-vs-history.
- Commit with a message that finishes "if applied, this commit will…". Then make TWO unrelated changes: fix a typo in a message AND add a comment block at the top. Stage and commit them SEPARATELY (git add -p lets you pick hunks if they're in one file) — two commits, two stories.
- Run git log --oneline: you should have 4+ commits reading like a changelog.
- Inspect: git show HEAD to see the newest snapshot's diff, then git show with the hash of your first commit. You just time-traveled — read-only, zero risk.
Ignore and undo — the safety drills
15 min- Run the tracker once so __pycache__/ or stray files might appear, and notice tasks.json changes on every run. Data files and caches don't belong in history. Create .gitignore containing the starter patterns, then git status — ignored files vanish from the listing. Add and commit the .gitignore itself.
- Undo drill 1 (working directory): deliberately vandalize tracker.py — delete half the file, save. Breathe. git restore tracker.py — vandalism gone, file restored to the last commit. This is the reload-the-save-point move.
- Undo drill 2 (staging): make a small edit, git add it, then unstage with git restore --staged tracker.py. Confirm with git status: the edit survives in the working directory, it's just off the tripod.
- Undo drill 3 (knowledge only): read what git reset --hard HEAD would do (working directory AND staging forced back to the last commit). Write one sentence on when it's dangerous — you'll use it deliberately on Day 20, never accidentally.
- Final check: git status is clean, git log tells this morning's story in order.
On your own
Commit surgery
15 minSimulate the messy afternoon every developer has: in your tracker repo, make three UNRELATED changes in one sitting — (a) add a "count" command that prints how many tasks are open, (b) rename a poorly-named variable throughout, (c) add usage instructions as comments or a docstring.
Goal: turn that mess into exactly three commits, each containing only its own change, each with a message that finishes "if applied, this commit will…". Use git add -p to split changes living in the same file. Finish with git log --oneline reading like a clean changelog, and git show on each commit proving nothing leaked between them.
Hints (only if stuck): in add -p, y stages a hunk, n skips it, s splits a big hunk. If two changes touch the same line, commit one, then make the other.
Bring the whole journey under version control
Promote git from experiment to habit: turn your entire ai-engineer-journey folder into a repository (either move the tracker repo up or init at the top level — decide and write one journal sentence on why). Create a proper top-level .gitignore (pycache, .env, backups/, app.log, data files you consider disposable — decide deliberately for each). Then build history that tells the true story in 4–6 commits: week-01 scripts, the journal, the toolbox module, the tracker, config files — grouped logically, not alphabetically. Every commit message must pass the "if applied, this commit will…" test. From tomorrow onward, the day isn't done until it's committed — that rule now applies for 172 more days.
Common mistakes & misconceptions
- Committing everything with git add . as a reflex. You'll snapshot caches, secrets, and half-finished junk together. Status first, stage deliberately, commit related changes together.
- Messages like "fix", "wip", "stuff". A message that doesn't say what changed makes history worthless for the person who needs it most — future you at midnight. Finish the sentence "this commit will…".
- Tracking generated or secret files (pycache, .env, API keys). Once a secret is committed it lives in history even after deletion — Day 44 covers why that's a real incident, not a nuisance. Ignore them from day one.
- Fearing commits because "it's not finished." Commits are save points, not press releases. Commit small and often; you can tidy before sharing (Day 20).
- Confusing restore with restore --staged. Plain restore DESTROYS uncommitted edits; --staged merely unstages. Read the command twice when the working directory holds unsaved work.
- Treating git as a backup that syncs somewhere. Local git protects against your own mistakes, not a dying disk — remote push (Day 20) adds the offsite copy.
Q1. You edited tracker.py and ran git add tracker.py, then edited it AGAIN. What does git commit snapshot?
Q2. Which command throws away your UNCOMMITTED changes to notes.py, restoring the last committed version?
Q3. Why put tasks.json and .env in .gitignore?
Go deeper — curated resources
- Pro Git 10.2 — Git objects: it's all content-addressed snapshots ↗ — Commits point to trees pointing to blobs, all named by hashes. Twenty minutes here and git stops being magic — branches (Day 20) become "just movable pointers".
- Journey repo initialized; log reads as a story; status clean
- All three undo drills performed (restore, restore --staged, reset read-only)
- Commit surgery: three isolated commits verified with git show
- The commit-every-day rule written into journal.md
- Quiz ≥ 2/3 (redo the cycle drill if you missed question 1)
← Back: Git lives in Day 6's terminal, and its first cargo is Day 7's tracker. The staging area's frame-the-shot discipline is Day 8's version of small functions from Day 3: coherent units, deliberately chosen.
Forward →: Day 14's checkpoint requires a clean history, graded. Day 20 adds remotes, branches, and pull requests; Day 21 ships a package from this repo. From Day 141, commits trigger eval gates in CI, and on Day 152 a push deploys to production — the same three commands you learned today, with higher stakes.
Unlocks: D14 Week 2 Checkpoint: Log Analyzer · D20 GitHub Collaboration · D81 Experiment Tracking & Reproducibility