Exercises 1-5 run in a lab repo (
~/dev/git-lab) so you can break things fearlessly. Exercise 6 goes on your real TicketFlow. Do not look at solutions.md before submitting.
Setup:
mkdir -p ~/dev/git-lab && cd ~/dev/git-lab
git init && echo "# Git Lab" > README.md
git add . && git commit -m "chore: lab starts"Exercise 1 — Commits with intention (add -p)
- Edit a file
app.pyadding TWO independent changes: a fix (typo in an error message) and a feature (a new function). All in the same file. - With
git add -p, split into two commits:fix: correct error messageandfeat: add function X. (usesto split hunks if needed; if the changes share a hunk, separate them by editing withe). git log --oneline: did you end up with two clean commits? What would have happened withgit add.and a single "update" commit?
Exercise 2 — Interactive rebase: the history you will tell yourself
- Make three careless commits:
echo 1 > a.txt; git add.; git commit -m "wip", thenecho 2 >> a.txt;... -m "fix"andecho 3 >> a.txt;... -m "wip2". git rebase -i HEAD~3and withsquash/rewordturn them into a singlefeat: add counters to a.txt.git log --oneline: compare before and after. Which commits disappear (old hashes)? Why is it safe here and dangerous on a shared branch?
Exercise 3 — Simulated and solved conflict
- Create branch
feature-a: change line 1 ofREADME.mdto "Version A" and commit. Back onmain, change the same line to "Version B" and commit. git merge feature-a: what does Git say exactly? Open the file and examine the<<<<<<< ======= >>>>>>>markers.- Resolve (pick A, B or a third wording),
git addand finish the merge. Delete the branch.git log --graph --oneline --all: describe the resulting graph. - Repeat the scenario with rebase instead of merge (new branch, same conflict): how does the final graph differ?
Exercise 4 — Rescue with reflog
- In the lab, make any commit and note its hash:
git log --oneline -1. - "Shoot yourself in the foot":
git reset --hard HEAD~1. - Find the "lost" commit with
git reflogand recover it withgit reset --hard HEAD@{n}(or create a branch pointing at it). Verify withgit log. - Write in one line when you would use
reflogvsgit revert(hint: did the commit already reach the shared main?).
Exercise 5 — Bisect with an automatic suite
- Create a
test.shscript that fails if the filebug.txtexists:
#!/usr/bin/env bash
if [[ -f bug.txt ]]; then echo "FAIL"; exit 1; fi
echo "OK"; exit 0- Make 5 commits; on the 4th create
bug.txt(and on the 5th add a different file). - Run:
git bisect start HEAD HEAD~4(bad = HEAD, good = 4 back) and thengit bisect run./test.sh. Which commit does it point at? Does it match the one that created the bug? git bisect reset. How many tests did Git run to locate it? How many would you have done by hand?
Exercise 6 — GitHub Flow on your TicketFlow (solo simulation)
- On your real repo: create
feat/detailed-healthand add a/api/health/detail/endpoint returning the process version and uptime (2 fields, little code). - Commit with the full conventional message (feat + body with the why) and push the branch to GitHub (
git push -u origin feat/detailed-health). - Open the PR: conventional title, description with context and a checklist. Review yourself with two honest observations.
- Merge with squash.
git log --oneline: how did history end up? Was the branch deleted (the button's option)?
Submit
Paste the outputs (log --graph, reflog, bisect result) and the link/content of your PR. Lesson 06 closes and with it the whole Module 1: we move to Lesson 07 — Advanced SQL (module 2, the craft's most decisive skill).