Files
gh-ypares-agent-skills-ypar…/skills/working-with-jj/references/batch-operations.md
2025-11-30 09:08:16 +08:00

166 lines
4.0 KiB
Markdown

# Batch Operations on Multiple Revisions
## Problem
When you need to update descriptions for multiple revisions (e.g., replacing line number references with labels), bash syntax and piping can be tricky.
## Anti-Pattern
```bash
# ❌ This will fail with syntax errors
for rev in unxn mktt stnq; do
jj log -r $rev | sed 's/L123/label/' | jj desc -r $rev --stdin
done
# Issues:
# 1. Missing -n1 --no-graph -T description (gets full log output)
# 2. Unquoted variables ($rev) can break with special chars
# 3. Complex pipes in one-liners are fragile
```
## Pattern 1: Intermediate Files (Recommended)
```bash
# ✅ Robust pattern using temporary files
for rev in unxn mktt stnq rwyq roww; do
# Extract description to file
jj log -r "$rev" -n1 --no-graph -T description > /tmp/desc_${rev}_old.txt
# Transform using sed/awk/etc
sed -f /tmp/replacements.sed /tmp/desc_${rev}_old.txt > /tmp/desc_${rev}_new.txt
# Apply back to revision
jj desc -r "$rev" --stdin < /tmp/desc_${rev}_new.txt
done
echo "✅ All descriptions updated"
```
**Benefits:**
- Each step is visible and debuggable
- Can inspect intermediate files if something goes wrong
- Easy to retry individual revisions
- Works with complex transformations
## Pattern 2: One Command at a Time
```bash
# ✅ Alternative: Sequential approach
jj log -r unxn -n1 --no-graph -T description | \
sed 's/L123/@label/' > /tmp/desc_unxn.txt
jj desc -r unxn --stdin < /tmp/desc_unxn.txt
jj log -r mktt -n1 --no-graph -T description | \
sed 's/L123/@label/' > /tmp/desc_mktt.txt
jj desc -r mktt --stdin < /tmp/desc_mktt.txt
# etc.
```
**Benefits:**
- Even more explicit
- Easy to stop/resume
- Perfect for copy-paste execution
## Pattern 3: Using sed Script File
```bash
# Create reusable sed script
cat > /tmp/replacements.sed << 'EOF'
s/L596-617/@types-de-cartes/g
s/L1242-1253/@carte-eglise/g
s/L659-665/@couts-marche/g
EOF
# Apply to all revisions
for rev in unxn mktt stnq; do
jj log -r "$rev" -n1 --no-graph -T description | \
sed -f /tmp/replacements.sed | \
jj desc -r "$rev" --stdin
done
```
**Benefits:**
- Reusable transformation logic
- Easy to test sed script independently
- Cleaner loop body
## Common Mistakes
### 1. Missing Template Specification
```bash
# ❌ Wrong: gets formatted log output
jj log -r xyz | sed 's/old/new/'
# ✅ Correct: extract just description
jj log -r xyz -n1 --no-graph -T description | sed 's/old/new/'
```
### 2. Unquoted Variables
```bash
# ❌ Breaks with special characters in rev names
for rev in a b c; do
jj log -r $rev # Unquoted
done
# ✅ Always quote
for rev in a b c; do
jj log -r "$rev" # Quoted
done
```
### 3. Fragile One-Liners
```bash
# ❌ Hard to debug, fragile
for rev in a b c; do jj log -r $rev -n1 --no-graph -T description | sed 's/x/y/' | jj desc -r $rev --stdin; done
# ✅ Readable, debuggable
for rev in a b c; do
jj log -r "$rev" -n1 --no-graph -T description | \
sed 's/x/y/' > /tmp/desc_${rev}.txt
jj desc -r "$rev" --stdin < /tmp/desc_${rev}.txt
done
```
## Real-World Example
Replacing all line number references with Typst labels across 10 revisions:
```bash
# 1. Create sed replacement script
cat > /tmp/sed_replacements.txt << 'EOF'
s/5F\.typ L596-617/5F.typ @types-de-cartes/g
s/5F\.typ L1242-1253/5F.typ @carte-eglise-en-pierre/g
s/5F\.typ L659-665/5F.typ @couts-marche/g
# ... etc
EOF
# 2. Process each revision
for rev in unxn mktt stnq rwyq roww wltq syun zkru mszz ovrv; do
jj log -r "$rev" -n1 --no-graph -T description | \
sed -f /tmp/sed_replacements.txt > "/tmp/desc_${rev}_new.txt"
jj desc -r "$rev" --stdin < "/tmp/desc_${rev}_new.txt"
done
# 3. Verify one result
jj log -r mktt -n1 --no-graph -T description | head -5
```
## Verification
Always verify the results after batch operations:
```bash
# Quick check: first line of each description
for rev in unxn mktt stnq; do
echo "=== $rev ==="
jj log -r "$rev" -n1 --no-graph -T description | head -3
done
# Or use jj log with custom template
jj log -r 'unxn | mktt | stnq' -T 'change_id.shortest(4) ++ " " ++ description.first_line() ++ "\n"'
```