Skip to content

Commit abfe67e

Browse files
update(update.md): refine worktree usage for library management
- Replace patch-based approach with worktree method for isolating library changes - Update steps for creating worktrees and managing library files - Add cleanup instructions for worktrees after processing - Include syncing main branch after PR merges
1 parent 195014d commit abfe67e

2 files changed

Lines changed: 36 additions & 45 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ nul
227227
# Project-specific
228228
temp/
229229
.update-preview/
230+
.worktrees/
230231

231232
# Agentic runs output
232233
agentic/runs/

agentic/commands/update.md

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -315,49 +315,31 @@ pattern `implementation/{spec-id}/{library}`. Therefore, each library MUST get i
315315

316316
Get `{owner}/{repo}` from `git remote get-url origin`.
317317

318-
**Why patches?** You cannot simply `git checkout -b` and `git add` because the working tree has modifications
319-
to ALL libraries at once. Switching branches with uncommitted changes either fails or carries changes across
320-
branches. Using `git stash` risks losing changes if the stash is dropped or if `git checkout main -- file`
321-
is used (which overwrites working tree files with main's version). The patch-based approach isolates each
322-
library's changes cleanly.
318+
**Why worktrees?** The main working tree contains modifications to ALL libraries (and potentially from other
319+
parallel `/update` instances for different specs). Using `git stash`/`git checkout` would conflict with parallel
320+
instances sharing the same stash stack and HEAD. `git worktree` creates an isolated working copy per branch —
321+
each has its own HEAD, index, and working tree. Only the specific library's files are copied in, making it
322+
physically impossible to accidentally commit another spec's changes.
323323

324-
**Step 1: Create per-library patch files**
325-
326-
For each library, create a patch containing only that library's changes:
327-
328-
```bash
329-
git diff -- plots/{spec_id}/implementations/{library}.py plots/{spec_id}/metadata/{library}.yaml \
330-
> /tmp/patch-{spec_id}-{library}.patch
331-
```
332-
333-
If the spec was changed, include it in the **first** library's patch only:
334-
335-
```bash
336-
git diff -- plots/{spec_id}/implementations/{library}.py plots/{spec_id}/metadata/{library}.yaml \
337-
plots/{spec_id}/specification.md > /tmp/patch-{spec_id}-{library}.patch
338-
```
339-
340-
**Step 2: Stash all changes**
341-
342-
```bash
343-
git stash
344-
```
345-
346-
**Step 3: For each library, create branch → apply patch → commit → push → PR**
324+
**Step 1: For each library, create worktree → copy files → commit → push → PR**
347325

348326
Run sequentially for each library:
349327

350328
```bash
351-
# Start from clean main
352-
git checkout main
329+
WORKTREE=".worktrees/{spec_id}-{library}"
330+
331+
# Create worktree with new branch based on main
332+
git worktree add -b implementation/{spec_id}/{library} "$WORKTREE" main
353333

354-
# Create per-library branch
355-
git checkout -b implementation/{spec_id}/{library}
334+
# Copy only this library's changed files into the worktree
335+
cp plots/{spec_id}/implementations/{library}.py "$WORKTREE/plots/{spec_id}/implementations/{library}.py"
336+
cp plots/{spec_id}/metadata/{library}.yaml "$WORKTREE/plots/{spec_id}/metadata/{library}.yaml"
337+
# If spec was changed (only for the first library):
338+
cp plots/{spec_id}/specification.md "$WORKTREE/plots/{spec_id}/specification.md"
356339

357-
# Apply only this library's patch
358-
git apply /tmp/patch-{spec_id}-{library}.patch
340+
# Commit and push from the worktree
341+
cd "$WORKTREE"
359342

360-
# Stage and commit
361343
git add plots/{spec_id}/implementations/{library}.py
362344
git add plots/{spec_id}/metadata/{library}.yaml
363345
# If spec was changed (only in first library branch):
@@ -367,10 +349,9 @@ git commit -m "update({spec_id}): {library} — {short description}
367349
368350
{description}"
369351

370-
# Push
371352
git push -u origin implementation/{spec_id}/{library}
372353

373-
# Create PR
354+
# Create PR (gh works in worktree context)
374355
gh pr create \
375356
--title "update({spec_id}): {library} — {short description}" \
376357
--body "$(cat <<EOF
@@ -401,19 +382,21 @@ PR_NUMBER=$(gh pr view --json number -q '.number')
401382
gh api repos/{owner}/{repo}/dispatches \
402383
-f event_type=review-pr \
403384
-f 'client_payload[pr_number]='"$PR_NUMBER"
404-
```
405-
406-
**Step 4: Return to main and restore working tree**
407385

408-
```bash
409-
git checkout main
410-
git stash pop
386+
# Return to repo root
387+
cd -
411388
```
412389

413-
**Step 5: Clean up patch files**
390+
**Step 2: Clean up worktrees**
391+
392+
After all libraries are processed:
414393

415394
```bash
416-
rm -f /tmp/patch-{spec_id}-*.patch
395+
# Remove each worktree
396+
git worktree remove .worktrees/{spec_id}-{library} --force
397+
398+
# After all worktrees removed, prune stale entries
399+
git worktree prune
417400
```
418401

419402
Report all PR URLs to the user.
@@ -499,6 +482,13 @@ Once all PRs have reached a terminal state:
499482

500483
2. Report any `not-feasible` libraries to the user — these may need manual intervention or a different approach.
501484

485+
3. Pull main to sync the merged changes:
486+
```bash
487+
git checkout main
488+
git pull origin main
489+
```
490+
This ensures the working tree is clean and up-to-date with all merged PRs.
491+
502492
---
503493

504494
## Library Agent Prompt

0 commit comments

Comments
 (0)