#!/usr/bin/env bash set -euo pipefail # Auto-sync Claude Project Knowledge when a commit touched any configured doc. REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)" if [ -z "${REPO_ROOT}" ]; then exit 0 fi cd "${REPO_ROOT}" CONF_FILE=".claude-sync.conf" SYNC_SCRIPT="scripts/sync-claude-docs.sh" if [ ! -f "${CONF_FILE}" ] || [ ! -f "${SYNC_SCRIPT}" ]; then exit 0 fi # Files changed in the commit we just made. # Merge commits: `git diff-tree HEAD` without a range returns the # combined-condensed diff (empty for clean, no-conflict merges), # which would skip regen on merges that bring in watched files via # the merged branch. Use a range against the first parent when HEAD # has two parents; plain HEAD for regular commits. if git rev-parse --verify HEAD^2 >/dev/null 2>&1; then changed="$(git diff-tree --no-commit-id --name-only -r HEAD^1 HEAD 2>/dev/null || true)" else changed="$(git diff-tree --no-commit-id --name-only -r HEAD 2>/dev/null || true)" fi if [ -z "${changed}" ]; then exit 0 fi # Configured paths (strip # comments and blanks). configured="$(awk ' { sub(/#.*/, "") gsub(/^[[:space:]]+|[[:space:]]+$/, "") if (length($0) > 0) print } ' "${CONF_FILE}")" match=0 while IFS= read -r cfile; do [ -z "${cfile}" ] && continue case "${cfile}" in .claude-sync.conf|scripts/sync-claude-docs.sh|.githooks/*) match=1; break ;; esac while IFS= read -r conf_path; do [ -z "${conf_path}" ] && continue if [ "${cfile}" = "${conf_path}" ]; then match=1 break 2 fi done <