diff --git a/sync.sh b/sync.sh index 5f63ca2..d273d90 100755 --- a/sync.sh +++ b/sync.sh @@ -1,25 +1,96 @@ #!/bin/bash -# Hermes Sync Script +# Hermes Sync Script - 双向同步记忆和技能 +# 使用方法: +# ./sync.sh pull - 从远程拉取到本地 +# ./sync.sh push - 从本地上传到远程 +# ./sync.sh sync - 双向同步 + set -e + +HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}" SYNC_DIR="/root/hermes-sync-tmp" -BRANCH="$(hostname)" cd "$SYNC_DIR" -case "$1" in - push) - cp /root/.hermes/memories/MEMORY.md memories/ 2>/dev/null || true - cp -r /root/.hermes/skills/github skills/github 2>/dev/null || true +RED='\033[0;31m' +GREEN='\033[0;32m' +NC='\033[0m' +info() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $*"; } +error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $*"; } + +pull() { + info "Pulling from remote..." + + # Fetch remote changes + git fetch origin main 2>/dev/null || { info "Remote empty, skipping pull"; return 0; } + + # Pull with rebase (preserves local changes) + if git diff HEAD origin/main --quiet 2>/dev/null; then + info "Already up to date" + return 0 + fi + + # Stash local changes first + if ! git diff --quiet; then + info "Stashing local changes..." + git stash push -m "local $(date)" || true + fi + + # Pull remote + if git rev-parse origin/main >/dev/null 2>&1; then + git rebase origin/main || { + error "Rebase conflict! Resolve manually in $SYNC_DIR" + git rebase --abort + git stash pop + return 1 + } + fi + + # Restore stashed changes + if git stash list | grep -q "local"; then + info "Restoring local changes..." + git stash pop || true + fi + + # Copy synced content to hermes home + cp "$SYNC_DIR/memories/MEMORY.md" "$HERMES_HOME/memories/MEMORY.md" 2>/dev/null || true + + # Sync skills (merge mode - don't delete local) + if [ -d "$SYNC_DIR/skills" ] && [ "$(ls -A "$SYNC_DIR/skills" 2>/dev/null)" ]; then + rsync -a --ignore-existing "$SYNC_DIR/skills/" "$HERMES_HOME/skills/" 2>/dev/null || \ + cp -rn "$SYNC_DIR/skills/"* "$HERMES_HOME/skills/" 2>/dev/null || true + fi + + info "Pull complete" +} + +push() { + info "Pushing to remote..." + + # Copy current hermes content to sync dir + cp "$HERMES_HOME/memories/MEMORY.md" "$SYNC_DIR/memories/MEMORY.md" 2>/dev/null || true + + # Sync skills (only add new ones, don't overwrite existing local modifications) + if [ -d "$HERMES_HOME/skills" ]; then + rsync -a --update "$HERMES_HOME/skills/" "$SYNC_DIR/skills/" 2>/dev/null || \ + cp -rn "$HERMES_HOME/skills/"* "$SYNC_DIR/skills/" 2>/dev/null || true + fi + + # Commit if there are changes + if git diff --quiet && git diff --cached --quiet; then + info "Nothing to push" + return 0 + fi + git add -A git commit -m "Sync $(date '+%Y-%m-%d %H:%M')" || true - git push origin main || true - ;; - pull) - git fetch origin - git checkout HEAD -- memories/ skills/ 2>/dev/null || true - cp memories/MEMORY.md /root/.hermes/memories/ 2>/dev/null || true - cp -r skills/github /root/.hermes/skills/ 2>/dev/null || true - ;; - *) - echo "Usage: $0 {push|pull}" - ;; + git push origin main || { error "Push failed!"; return 1; } + + info "Push complete" +} + +case "${1:-}" in + pull) pull ;; + push) push ;; + sync) pull; push ;; + *) echo "Usage: $0 {pull|push|sync}"; exit 1 ;; esac