BurningTimesAi/scripts/sync_memory_repo_to_central.sh

67 lines
2.3 KiB
Bash

#!/bin/bash
# SessionStart hook — 레포 memory/org/ → 중앙 $HOME/.claude/nerdnavis-memory/ 단방향 sync
# git pull 직후 원격 반영분을 중앙에 최신화. unflushed 중앙 변경은 대피 백업.
# 2026-04-19 신설 — C34-3 동기화 4계층 (레포 SOT 원칙)
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
[ -z "$REPO_ROOT" ] && exit 0
REPO_MEM="$REPO_ROOT/memory/org"
CENTRAL_MEM="$HOME/.claude/nerdnavis-memory"
MARKER_NAME=".memory-junction-marker"
LOCK_FILE="$HOME/.claude/.nerdnavis_memory_sync.lock"
[ ! -d "$REPO_MEM" ] && exit 0
# 0. Lock (race condition 방지, 5초 타임아웃)
ATTEMPT=0
while [ -f "$LOCK_FILE" ] && [ "$ATTEMPT" -lt 5 ]; do
sleep 1
ATTEMPT=$((ATTEMPT + 1))
done
echo "$$" > "$LOCK_FILE" 2>/dev/null
trap 'rm -f "$LOCK_FILE"' EXIT
# 1. 중앙 저장소 보장
mkdir -p "$CENTRAL_MEM" 2>/dev/null
[ ! -f "$CENTRAL_MEM/$MARKER_NAME" ] && echo "nerdnavis-memory central (C34-16, 2026-04-19)" > "$CENTRAL_MEM/$MARKER_NAME"
# 2. unflushed 중앙 변경 탐지 (중앙 mtime > 레포 mtime + HEAD 미반영 의심)
CONFLICT_COUNT=0
for cf in "$CENTRAL_MEM"/*.md "$CENTRAL_MEM"/*.json; do
[ -f "$cf" ] || continue
basename=$(basename "$cf")
[ "$basename" = "$MARKER_NAME" ] && continue
rf="$REPO_MEM/$basename"
if [ -f "$rf" ]; then
# 양쪽 존재: mtime 비교 (중앙이 더 새로우면 unflushed 후보)
if [ "$cf" -nt "$rf" ]; then
# 내용 비교로 확정 (mtime만 다르고 내용 같으면 touch)
if ! diff -q "$cf" "$rf" >/dev/null 2>&1; then
CONFLICT_COUNT=$((CONFLICT_COUNT + 1))
fi
fi
else
# 중앙에만 있고 레포에 없음 — unflushed 신규 파일
CONFLICT_COUNT=$((CONFLICT_COUNT + 1))
fi
done
# 3. 충돌 있으면 중앙 대피 후 진행
if [ "$CONFLICT_COUNT" -gt 0 ]; then
STAMP=$(date +%Y%m%d%H%M%S)
CONFLICT_DIR="$CENTRAL_MEM.conflict-$STAMP"
cp -r "$CENTRAL_MEM" "$CONFLICT_DIR" 2>/dev/null
echo "⚠️ [Memory Sync] unflushed 중앙 변경 $CONFLICT_COUNT 건 감지 — 대피: $CONFLICT_DIR" >&2
fi
# 4. 레포 → 중앙 복사 (marker·conflict 제외, 삭제 동기화 안 함 — 안전망)
for f in "$REPO_MEM"/*.md "$REPO_MEM"/*.json; do
[ -f "$f" ] || continue
basename=$(basename "$f")
cp "$f" "$CENTRAL_MEM/$basename" 2>/dev/null
done
exit 0