Running-example consistency: paths, tasks.json, command collisions (#7,#10,#11) (#57)
Co-authored-by: claude <claude@jpaul.io> Co-committed-by: claude <claude@jpaul.io>
This commit was merged in pull request #57.
This commit is contained in:
@@ -175,9 +175,9 @@ decide:
|
||||
|
||||
```python
|
||||
<<<<<<< HEAD
|
||||
print("usage: python cli.py [add <title> | list | done <index> | count]")
|
||||
print("usage: python cli.py [add <title> | list | done <index> | stats]")
|
||||
=======
|
||||
print("usage: python cli.py [add <title> | list | done <index> | clear]")
|
||||
print("usage: python cli.py [add <title> | list | done <index> | purge]")
|
||||
>>>>>>> experiment
|
||||
```
|
||||
|
||||
@@ -190,7 +190,7 @@ Read it like this:
|
||||
the file so it contains the version you want and deleting all three marker lines.**
|
||||
|
||||
You're not picking a side mechanically — you're deciding what the line *should* say. Often that's one
|
||||
side, sometimes it's a blend of both (here: a usage string that lists *both* `count` and `clear`).
|
||||
side, sometimes it's a blend of both (here: a usage string that lists *both* `stats` and `purge`).
|
||||
Then you tell Git the conflict is settled:
|
||||
|
||||
```bash
|
||||
@@ -324,44 +324,52 @@ attempts become free to reject.
|
||||
Now the skill everyone fears and nobody should. You'll engineer a guaranteed conflict by having
|
||||
**two branches change the same line in different ways**, then resolve it.
|
||||
|
||||
1. Make sure you're on a clean `main`. Create the first branch and have the AI add a `count` command:
|
||||
> **Starting state.** By now your `tasks-app` has accumulated commands from earlier modules, so your
|
||||
> `usage:` line is longer than the bare `[add <title> | list | done <index>]` you started with — and
|
||||
> that's fine. This lab works *regardless* of what's on that line, because the collision is just "two
|
||||
> branches each appended a different new command to the same usage line." To make it reproduce even on
|
||||
> a carried-forward app, we deliberately add two commands you **haven't** built yet — `stats` and
|
||||
> `purge`. (Any two brand-new commands would do; the point is the same line, edited two ways.) The
|
||||
> marker examples below show the shape; your real markers will carry your fuller usage string.
|
||||
|
||||
1. Make sure you're on a clean `main`. Create the first branch and have the AI add a `stats` command:
|
||||
|
||||
```bash
|
||||
git switch main
|
||||
git switch -c feature/count
|
||||
git switch -c feature/stats
|
||||
```
|
||||
|
||||
Ask the AI: *"Add a `count` command to `cli.py` that prints how many tasks are pending, and update
|
||||
the usage string to include it."* Then:
|
||||
Ask the AI: *"Add a `stats` command to `cli.py` that prints how many tasks are total, done, and
|
||||
pending, and update the usage string to include it."* Then:
|
||||
|
||||
```bash
|
||||
git diff # confirm it edited the usage line + added the command
|
||||
git add . && git commit -m "Add count command"
|
||||
git add . && git commit -m "Add stats command"
|
||||
```
|
||||
|
||||
2. Switch back to `main` and create a *different* branch that touches **the same usage line**:
|
||||
|
||||
```bash
|
||||
git switch main
|
||||
git switch -c feature/clear
|
||||
git switch -c feature/purge
|
||||
```
|
||||
|
||||
Ask the AI: *"Add a `clear` command to `cli.py` that deletes all tasks, and update the usage
|
||||
string to include it."* Then:
|
||||
Ask the AI: *"Add a `purge` command to `cli.py` that removes all completed (done) tasks, and update
|
||||
the usage string to include it."* Then:
|
||||
|
||||
```bash
|
||||
git diff # it also edited the usage line — this is the collision to come
|
||||
git add . && git commit -m "Add clear command"
|
||||
git add . && git commit -m "Add purge command"
|
||||
```
|
||||
|
||||
Both branches changed the same `usage:` line, each adding a *different* command to it. Git will
|
||||
not be able to auto-merge that line.
|
||||
|
||||
3. Merge them and watch it conflict. Merge `feature/count` into `feature/clear` (you're on
|
||||
`feature/clear`):
|
||||
3. Merge them and watch it conflict. Merge `feature/stats` into `feature/purge` (you're on
|
||||
`feature/purge`):
|
||||
|
||||
```bash
|
||||
git merge feature/count
|
||||
git merge feature/stats
|
||||
```
|
||||
|
||||
Git stops with a conflict and tells you which file is unmerged. Confirm:
|
||||
@@ -370,28 +378,30 @@ Now the skill everyone fears and nobody should. You'll engineer a guaranteed con
|
||||
git status # cli.py listed under "Unmerged paths"
|
||||
```
|
||||
|
||||
4. Open `cli.py` and find the conflict markers around the usage line:
|
||||
4. Open `cli.py` and find the conflict markers around the usage line (your usage string will be
|
||||
longer — it carries the commands from earlier modules — but the collision is exactly this: both
|
||||
branches appended a different new command to it):
|
||||
|
||||
```python
|
||||
<<<<<<< HEAD
|
||||
print("usage: python cli.py [add <title> | list | done <index> | clear]")
|
||||
print("usage: python cli.py [add <title> | list | done <index> | purge]")
|
||||
=======
|
||||
print("usage: python cli.py [add <title> | list | done <index> | count]")
|
||||
>>>>>>> feature/count
|
||||
print("usage: python cli.py [add <title> | list | done <index> | stats]")
|
||||
>>>>>>> feature/stats
|
||||
```
|
||||
|
||||
(The command bodies for `count` and `clear` touch different lines, so Git merged *those* cleanly
|
||||
(The command bodies for `stats` and `purge` touch different lines, so Git merged *those* cleanly
|
||||
on its own — the only collision is the usage string both branches edited.)
|
||||
|
||||
5. **Resolve it with the AI.** With your editor-integrated agent, this is its sweet spot. Ask:
|
||||
|
||||
> *"`cli.py` has a merge conflict on the usage line. I want the final version to list BOTH the
|
||||
> `count` and `clear` commands. Resolve the conflict and remove the markers."*
|
||||
> `stats` and `purge` commands. Resolve the conflict and remove the markers."*
|
||||
|
||||
It should produce a single, marker-free line listing both commands, e.g.:
|
||||
|
||||
```python
|
||||
print("usage: python cli.py [add <title> | list | done <index> | count | clear]")
|
||||
print("usage: python cli.py [add <title> | list | done <index> | stats | purge]")
|
||||
```
|
||||
|
||||
**Verify its work — this is the part the AI can get subtly wrong.** A conflict resolver can
|
||||
@@ -401,8 +411,8 @@ Now the skill everyone fears and nobody should. You'll engineer a guaranteed con
|
||||
```bash
|
||||
git diff # check ONLY what you intended changed; no markers remain
|
||||
python cli.py # run with no args — see the merged usage string
|
||||
python cli.py count # both commands actually work
|
||||
python cli.py clear
|
||||
python cli.py stats # both commands actually work
|
||||
python cli.py purge
|
||||
```
|
||||
|
||||
6. Tell Git the conflict is settled and complete the merge:
|
||||
@@ -419,10 +429,13 @@ Now the skill everyone fears and nobody should. You'll engineer a guaranteed con
|
||||
|
||||
> **Guaranteed-conflict generator.** AI edits are nondeterministic, so if the agent didn't touch the
|
||||
> same line on both branches and you *didn't* get a conflict in step 3, run the helper script to
|
||||
> manufacture one deterministically, then practice steps 4–6 on it:
|
||||
> manufacture one deterministically, then practice steps 4–6 on it. Copy it into your `tasks-app`
|
||||
> first (the course's lab scripts live in the course repo, not in `tasks-app` — see Module 4's
|
||||
> *You'll need*), then run it from inside the repo:
|
||||
>
|
||||
> ```bash
|
||||
> bash modules/06-branches-sandboxes-for-experiments/lab/make-conflict.sh
|
||||
> cp /path/to/modules/06-branches-sandboxes-for-experiments/lab/make-conflict.sh .
|
||||
> bash make-conflict.sh
|
||||
> ```
|
||||
>
|
||||
> It creates two branches that both edit the same line of `README.md`, leaving you mid-conflict with
|
||||
|
||||
Reference in New Issue
Block a user