Designed for Codex/Claude Code and scripts to use diffk reliably and predictably.
- Ensure session (idempotent):
diffk init --mode=new-branch --source <branch> --install-hooks --no-upstream --if-missing --dirty commit --snapshot-message "Warmup snapshot" --output json
- If switching
--sourceand the worktree is dirty, you may getDIRTY_WORKTREE(13). Retry with--dirty=stash(you can still set--snapshot-message/--snapshot-message-file; it applies only if a snapshot commit actually happens):
diffk init --mode=new-branch --source <branch> --if-missing --dirty stash --snapshot-message-file .snapshot-msg.txt --output json
- For each change:
- Optional pre-check then apply patch to index:
diffk stage --stdin --check-only --output json < patch.diff
if ok then: diffk stage --stdin --output json < patch.diff
- Commit:
diffk commit --title "AI: update" --output json
- Finish:
diffk squash --message "Squash: AI session summary" --output json
# Dry-run merge to detect conflicts
m=$(diffk merge --to <branch> --strategy=squash --dry-run --output json)
# If ok, perform the merge (custom message optional)
diffk merge --to <branch> --strategy=squash --message "Squash: session" --output json
diffk end --output json
- Top-level:
version|command|code|status|data|error - Errors include:
error.message,error.hint,error.errorCode - Common
errorCodevalues and meanings:NO_SESSION(12),SESSION_EXISTS(11),DIRTY_WORKTREE(13),LOCKED(14),NOTHING_TO_COMMIT(15),CONFLICT(10),PATCH_APPLY_FAILED(41),NOT_GIT(20),INVALID_ARGS(2),INTERNAL(100/50)
- Ensure session (
init --if-missing→ handleDIRTY_WORKTREE) - Stage/commit loop (
stage --check-only→stage→commit; handlePATCH_APPLY_FAILEDandNOTHING_TO_COMMIT) squashmerge --dry-run(handleCONFLICT) →mergeend
--debug: print underlying git commands (to stderr)--timeout <ms>: per-command timeout (default 30000)- Process lock: commands acquire
.git/diffkeeper/lock; on contention you getLOCKED(14). Serialize or retry. If a crash leaves a stale lock, manually delete it after ensuring no activediffkprocess.
- Provide a
.gitignoreat repo root. Auto-snapshot oninit --dirty commitand normalcommitboth respect.gitignore. Without it, build/cache files may be committed accidentally.
- Generate minimal tolerant patches:
git diff -U0 -- <paths> > patch.diff(U0 pairs well with--unidiff-zero) --stdinreads from pipe/redirect; when run interactively with no input it waits for EOF (Ctrl-D)- Use
--reverseif your patch direction is inverted
- No interactive hunk picker; use prepared unified diffs with
stage merge --strategy=no-ffwithout--messageuses--no-editto avoid interactive editorff-onlyfast-forwards; no merge commit- Prefer
--message-filefor multi-line commit/merge messages (shell-safe)