Update Obsidian Notes from Git
Syncs git commit history into Obsidian task markdown files and project changelog.
Configuration
Read .claude/pm-config.json first. If missing, tell user to run /pm-init.
Mode
- •Interactive (default): Preview changes, ask confirmation before writing
- •Auto (
--autoflag orauto_mode: truein config): Write directly without prompts
Workflow
Delegate to the pm-updater agent (model: sonnet) with a prompt summarizing config and mode.
If running inline (no subagent available), follow these steps:
1. Find last sync point
Read changelog.md and find latest ## YYYY-MM-DD header to determine last update date.
2. Get commits since last update
git log --since="<date>" --format="%h|%s|%ci" --no-merges
Parse output to extract:
- •Commit hash
- •Commit message
- •Timestamp
3. Extract task associations
From each commit, extract task ID using:
- •Commit message patterns:
feat(TASK-001):,fix(TASK-002):, etc. - •Branch name:
feat/TASK-001-*,fix/TASK-002-*
Group commits by task ID. Unassociated commits go to separate bucket.
4. Process each task
For each task with commits:
a. Read task file: Load markdown from Obsidian directory
b. Analyze changes: Run git diff --stat <commits> to see affected files
c. Generate log entry: Write concise summary in English:
- •What changed (features, fixes, improvements)
- •Which files/modules affected
- •Include commit hashes for traceability d. Check criteria: Review completion criteria, suggest checking boxes if met e. Update status:
- •First commit on task:
⭕ to-do→⏳ in-progress - •All criteria checked:
⏳ in-progress→✅ completed - •User blocks: any status →
⏸️ pending - •User resumes:
⏸️ pending→⏳ in-progress - •User cancels: any status →
❌ cancelledf. Update frontmatter: - •Set
updatedfield to current date - •Update
task_statusif changed - •Fill
branchfield if empty and commit is on task branch - •Set
completed_timeif status changed to✅ completed
5. Write development logs
Use scripts/obsidian_pm.py append-log command:
- •Insert under
#### 🧮 Content:section - •Use
##### YYYY-MM-DDheaders - •Newest entries first (before older logs)
- •Format:
markdown
##### 2026-02-11 - Implemented authentication endpoints - Added JWT token generation - commits: `a1b2c3d`, `e4f5g6h`
6. Handle unassociated commits
Commits without task ID:
- •Interactive mode: Ask user which task to associate, or create new task
- •Auto mode: Log under "Unassociated Changes" section in changelog
7. Update changelog
Append to changelog.md under today's date:
## 2026-02-11 - 🔄 Updated [[TASK-001]]: Completed authentication system - 🔄 Updated [[TASK-002]]: Fixed login bug - 📝 Unassociated: Refactored utility functions
8. Summary output
Show user:
- •Tasks updated with status changes
- •Number of commits processed
- •Any unassociated commits that need attention
Status Transition Logic
First commit: ⭕ to-do → ⏳ in-progress All criteria met: ⏳ in-progress → ✅ completed Blocked: any → ⏸️ pending Resumed: ⏸️ pending → ⏳ in-progress Cancelled: any → ❌ cancelled
Script Utilities
- •
scripts/obsidian_pm.py list-tasks- List all tasks with status - •
scripts/obsidian_pm.py read-task- Read task frontmatter and body - •
scripts/obsidian_pm.py update-frontmatter- Update single field - •
scripts/obsidian_pm.py append-log- Add development log entry - •
scripts/obsidian_pm.py check-criteria- Check completion criteria box
For task format details, see reference/task-format.md.
Example
# Interactive mode /pm-update # Auto mode (no prompts) /pm-update --auto # Specific task only /pm-update TASK-001