Files
hermes-sync/sync.sh

129 lines
4.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Hermes Sync Script - 真正的双向合并同步
# 策略:先 pull合并远程再 push推送本地。不做 force push。
# 冲突处理MEMORY.md 使用 " ours" 策略(优先保留本地),其他文件手动合并
set -e
SYNC_DIR="${SYNC_DIR:-$HOME/.hermes-sync}"
HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
info() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $*"; }
warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARN:${NC} $*"; }
error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $*"; }
cd "$SYNC_DIR"
# 确保在 main 分支
git checkout main 2>/dev/null || true
# ===== 步骤 1: 复制本地文件到同步目录 =====
info "Staging local changes..."
cp "$HERMES_HOME/memories/MEMORY.md" "$SYNC_DIR/memories/MEMORY.md" 2>/dev/null || true
# 复制所有技能rsync 增量同步)
if [ -d "$HERMES_HOME/skills" ]; then
mkdir -p "$SYNC_DIR/skills"
rsync -a --delete "$HERMES_HOME/skills/" "$SYNC_DIR/skills/" 2>/dev/null || true
fi
git add -A
# 检查本地是否有变更
if git diff --cached --quiet && git diff --quiet; then
LOCAL_CHANGES=false
else
LOCAL_CHANGES=true
fi
# ===== 步骤 2: 拉取远程并合并 =====
info "Fetching remote changes..."
git fetch origin main
# 检查远程是否有新提交
if git rev-parse HEAD >/dev/null 2>&1 && \
git rev-parse origin/main >/dev/null 2>&1 && \
! git merge-base --is-ancestor HEAD origin/main 2>/dev/null; then
REMOTE_AHEAD=true
else
REMOTE_AHEAD=false
fi
if [ "$REMOTE_AHEAD" = true ]; then
info "Remote has new changes, merging..."
if [ "$LOCAL_CHANGES" = true ]; then
# 本地和远程都有改动 → 需要 merge
# 先暂存本地改动
git stash push -m "local before merge $(date)" 2>/dev/null || true
# 合并远程
if git merge origin/main --no-edit 2>/dev/null; then
info "Merge successful"
else
warn "Merge conflict, attempting auto-resolve..."
# 自动解决skills 目录的文件取两方混合保留ours
# MEMORY.md 取 ours
git checkout --ours memories/MEMORY.md 2>/dev/null || true
# 其他冲突文件取ours避免复杂冲突
git diff --name-only --diff-filter=U | grep -v "^memories/" | while read f; do
git checkout --ours "$f" 2>/dev/null || true
done
git add -A
git commit -m "Auto-resolve merge conflict $(date)" 2>/dev/null || true
fi
# 恢复本地改动并重新合并
if git stash list | grep -q "local before merge"; then
git stash pop || true
# 再次合并(这次远程 ours本地 theirs → 但 git 没有 --theirs 选项)
# 改用 rebase 策略
git rebase origin/main 2>/dev/null || {
warn "Rebase conflict, using ours strategy..."
git rebase --abort 2>/dev/null || true
git merge origin/main --no-edit 2>/dev/null || true
}
fi
else
# 只有远程有新改动 → 直接 merge
git merge origin/main --no-edit 2>/dev/null || {
warn "Fast-forward only merge..."
git merge --ff-only origin/main 2>/dev/null || {
git reset --hard origin/main
}
}
fi
else
info "Remote up to date"
fi
# ===== 步骤 3: 提交本地变更并推送 =====
if [ "$LOCAL_CHANGES" = true ]; then
info "Committing local changes..."
git commit -m "Sync $(date '+%Y-%m-%d %H:%M')" 2>/dev/null || true
info "Pushing to remote..."
if git push origin main 2>&1; then
info "Push successful"
else
warn "Push rejected (remote advanced), pulling and retrying..."
git pull origin main --no-edit 2>/dev/null || true
git push origin main 2>&1 || error "Push failed after retry"
fi
else
info "No local changes to push"
fi
# ===== 步骤 4: 合并结果应用到本地 hermes =====
info "Applying merged changes to local hermes..."
cp "$SYNC_DIR/memories/MEMORY.md" "$HERMES_HOME/memories/MEMORY.md" 2>/dev/null || true
# Skills: rsync 合并(不覆盖本地已有的,保留本地独有的)
if [ -d "$SYNC_DIR/skills" ]; 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 "Sync complete"