fix(modules-4,7,14): make the git demos/labs actually do what the prose claims
- M4 Part C now commits the reviewed `delete` change as the checkpoint, so Part D's `git restore .` returns to a delete-containing state (was wiping it). - M7 'watch it break': switch to an existing divergent branch so the "would be overwritten by checkout" refusal actually fires (git switch -c never did). - M7 Part C: demonstrate worktree isolation with existing add/list and distinct per-worktree data; move the new clear/count commands to after they exist. - M14 Part C: recover with `git revert HEAD` (Module 12, which precedes M14) so CI legitimately goes green; drop the wrong "Module 2's safety net" attribution. Closes #2 Closes #3 Closes #4 Closes #12 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfzV5QvtPDz8LJS3Pu5VLT
This commit is contained in:
@@ -56,22 +56,31 @@ That's fine when *you* are the only one standing on the floor. It falls apart th
|
||||
two things happening at once. Watch it break:
|
||||
|
||||
```bash
|
||||
# Agent A is mid-change on a feature branch — uncommitted edits in cli.py
|
||||
# Agent A added a `clear` command and committed it on its own branch:
|
||||
git switch -c feature/clear
|
||||
# ...agent A edits cli.py, hasn't committed...
|
||||
# ...agent A edits the usage line in cli.py to add `clear`...
|
||||
git commit -am "Add clear command"
|
||||
|
||||
# You want Agent B to start a different job, so you try to switch:
|
||||
# You start Agent B on a fresh branch off main; it begins editing the SAME
|
||||
# usage line to add `count`, and hasn't committed:
|
||||
git switch main
|
||||
git switch -c feature/count
|
||||
# ...agent B edits cli.py, hasn't committed...
|
||||
|
||||
# You try to hop the working directory back to Agent A's branch to check on it:
|
||||
git switch feature/clear
|
||||
# error: Your local changes to the following files would be overwritten by checkout:
|
||||
# cli.py
|
||||
# Please commit your changes or stash them before you switch branches.
|
||||
```
|
||||
|
||||
Git stops you — correctly. But now you're stuck choosing between bad options:
|
||||
Git stops you — correctly. Switching to `feature/clear` would overwrite Agent B's uncommitted edits
|
||||
to `cli.py` with Agent A's committed version of those same lines, so Git refuses rather than silently
|
||||
destroy the work. But now you're stuck choosing between bad options:
|
||||
|
||||
- **Commit half-finished work** just to get it out of the way (pollutes history, and Agent A's job
|
||||
isn't done).
|
||||
- **Stash it** (now Agent A's context lives in a stash you have to remember to pop, and Agent A — a
|
||||
- **Commit half-finished work** just to get it out of the way (pollutes history, and Agent B's
|
||||
`count` command isn't done).
|
||||
- **Stash it** (now Agent B's context lives in a stash you have to remember to pop, and Agent B — a
|
||||
long-running session that thinks its files are right there — is now editing files that silently
|
||||
changed under it).
|
||||
- **Run both agents on the same branch in the same folder** — and watch them overwrite each other's
|
||||
@@ -220,23 +229,40 @@ collide. Then you'll merge both back and clean up.
|
||||
|
||||
### Part A — Feel the collision (1 minute)
|
||||
|
||||
Before fixing it, reproduce the bottleneck from "Where branches alone run out." In your `tasks-app`:
|
||||
Before fixing it, reproduce the bottleneck from "Where branches alone run out." The wall only appears
|
||||
when both branches touch the **same line** of `cli.py` — one committed, one not — so we make each
|
||||
branch edit the usage line. (The `sed … > tmp && mv` is just a portable, copy-pasteable stand-in for
|
||||
the edit an agent would make.) In your `tasks-app`:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app
|
||||
git switch -c feature/scratch
|
||||
# make a fake uncommitted edit so the working dir is dirty:
|
||||
echo "# scratch" >> cli.py
|
||||
git switch -c feature/other
|
||||
|
||||
# Agent A's branch: add `clear` to the usage line and commit it.
|
||||
git switch -c feature/clear
|
||||
sed 's/done <index>/done <index> | clear/' cli.py > cli.tmp && mv cli.tmp cli.py
|
||||
git commit -am "Add clear command (demo)"
|
||||
|
||||
# Agent B's branch, off main: start adding `count` to the SAME line — leave it uncommitted.
|
||||
git switch main
|
||||
git switch -c feature/count
|
||||
sed 's/done <index>/done <index> | count/' cli.py > cli.tmp && mv cli.tmp cli.py
|
||||
|
||||
# Try to hop the working directory back to Agent A's branch:
|
||||
git switch feature/clear
|
||||
# error: Your local changes to the following files would be overwritten by checkout:
|
||||
# cli.py
|
||||
# Please commit your changes or stash them before you switch branches.
|
||||
```
|
||||
|
||||
Git refuses — it won't move you to another branch with uncommitted changes in the way. *That* is the
|
||||
wall. Clean up before continuing:
|
||||
Git refuses — moving the one working directory to `feature/clear` would overwrite Agent B's
|
||||
uncommitted edit with `feature/clear`'s committed version of that line. *That* is the wall: one
|
||||
directory can't hold two agents' in-progress work at once. These two branches existed only to feel
|
||||
the collision, so clean them up before continuing:
|
||||
|
||||
```bash
|
||||
git restore cli.py
|
||||
git restore cli.py # drop Agent B's uncommitted edit
|
||||
git switch main
|
||||
git branch -D feature/scratch feature/other
|
||||
git branch -D feature/clear feature/count # throw away the demo branches
|
||||
```
|
||||
|
||||
### Part B — Create two worktrees
|
||||
@@ -269,16 +295,19 @@ This is the part to actually *do simultaneously*, not one then the other.
|
||||
`lab/agent-a-prompt.md` — *add a `clear` command that removes all tasks.*
|
||||
2. Open `~/workflow-course/tasks-app-count` in a **second** editor/AI session. Give it the prompt in
|
||||
`lab/agent-b-prompt.md` — *add a `count` command that prints the number of pending tasks.*
|
||||
3. Let both work at the same time. While they run, prove the isolation from a third terminal:
|
||||
3. Let both work at the same time. While they run, prove the isolation from a third terminal — but
|
||||
use commands that **already exist**. (`clear` and `count` don't yet; the agents are still writing
|
||||
them.) Give each worktree its own task and list it:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app-clear && python cli.py clear # agent A's feature
|
||||
cd ~/workflow-course/tasks-app-count && python cli.py count # agent B's feature
|
||||
cd ~/workflow-course/tasks-app-clear && python cli.py add "from worktree A" && python cli.py list
|
||||
cd ~/workflow-course/tasks-app-count && python cli.py add "from worktree B" && python cli.py list
|
||||
```
|
||||
|
||||
Each app runs its own command in its own folder. Note that each worktree has its **own**
|
||||
`tasks.json` (it's gitignored runtime state, not shared history) — so the two running apps don't
|
||||
even share data. Total isolation.
|
||||
Each `list` shows only its own task — worktree A never sees "from worktree B" and vice versa. Each
|
||||
worktree has its **own** `tasks.json` (gitignored runtime state, not shared history), so the two
|
||||
running apps don't even share data. Separate files, separate state, while both agents work. Total
|
||||
isolation.
|
||||
|
||||
4. In each worktree, commit the agent's work on its own branch:
|
||||
|
||||
@@ -289,6 +318,16 @@ This is the part to actually *do simultaneously*, not one then the other.
|
||||
|
||||
Two agents, two commits, two branches — neither ever saw the other's files.
|
||||
|
||||
5. *Now* the new commands exist — run each in its own worktree to watch it work:
|
||||
|
||||
```bash
|
||||
cd ~/workflow-course/tasks-app-clear && python cli.py clear # agent A's new command
|
||||
cd ~/workflow-course/tasks-app-count && python cli.py count # agent B's new command
|
||||
```
|
||||
|
||||
`count` reports only worktree B's task — the one you added in step 3 — because B's `tasks.json` is
|
||||
the only state it can see. The isolation, one last time.
|
||||
|
||||
### Part D — Merge back and clean up
|
||||
|
||||
Bring both features home to `main` in your original worktree:
|
||||
@@ -354,8 +393,8 @@ Worktrees are sharp tools. The honest caveats:
|
||||
|
||||
**You're done when:**
|
||||
|
||||
- `git worktree list` showed three entries at once, and you ran a different command of the
|
||||
`tasks-app` from two different worktree folders.
|
||||
- `git worktree list` showed three entries at once, and you ran the `tasks-app` from two different
|
||||
worktree folders — adding a different task in each and watching each keep its own `tasks.json`.
|
||||
- You ran two AI sessions in parallel — each in its own worktree on its own branch — and confirmed
|
||||
neither touched the other's files (different folders, different `tasks.json`, different branch).
|
||||
- You merged both feature branches back into `main` (resolving a conflict if one appeared) and the
|
||||
|
||||
Reference in New Issue
Block a user