Team Ai
Apppublic

sin601/claude-code

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
git-sync.sh264 linesDownload Raw Back to scripts
1#!/bin/bash2# Git 双向同步服务3 4set -e5 6CONFIG_DIR="${CONFIG_DIR:-/config}"7WORK_DIR="${WORK_DIR:-/workspace}"8HOME="${HOME:-/root}"9 10# 加载配置11if [ -f "${CONFIG_DIR}/config.env" ]; then12    set -a13    source "${CONFIG_DIR}/config.env"14    set +a15fi16 17# 默认值18GIT_SYNC_INTERVAL="${GIT_SYNC_INTERVAL:-300}"19GIT_BRANCH="${GIT_BRANCH:-main}"20SYNC_EXCLUDE="${SYNC_EXCLUDE:-node_modules .git __pycache__ *.pyc .env *.log .cache tmp}"21COMMIT_PREFIX="${COMMIT_PREFIX:-[HF-Space]}"22 23# 日志函数24log() {25    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [git-sync] $1"26}27 28# 错误处理29error() {30    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [git-sync] ERROR: $1" >&231}32 33# 检查 Git 配置34check_git_config() {35    if [ -z "${GIT_REPO_URL}" ]; then36        log "GIT_REPO_URL not configured. Git sync disabled."37        return 138    fi39    40    if [ -z "${GIT_TOKEN}" ]; then41        log "GIT_TOKEN not configured. Git sync disabled."42        return 143    fi44    45    return 046}47 48# 配置 Git 远程仓库49setup_remote() {50    cd "${WORK_DIR}"51    52    # 构建带认证的 URL53    if [[ "${GIT_REPO_URL}" == https://github.com/* ]]; then54        AUTH_URL="https://${GIT_TOKEN}@github.com/${GIT_REPO_URL#https://github.com/}"55    elif [[ "${GIT_REPO_URL}" == https://gitlab.com/* ]]; then56        AUTH_URL="https://oauth2:${GIT_TOKEN}@gitlab.com/${GIT_REPO_URL#https://gitlab.com/}"57    elif [[ "${GIT_REPO_URL}" == https://huggingface.co/* ]]; then58        AUTH_URL="https://user:${GIT_TOKEN}@huggingface.co/${GIT_REPO_URL#https://huggingface.co/}"59    else60        AUTH_URL="${GIT_REPO_URL}"61    fi62    63    # 检查是否已有远程仓库64    if git remote | grep -q "^origin$"; then65        git remote set-url origin "${AUTH_URL}"66    else67        git remote add origin "${AUTH_URL}"68    fi69    70    log "Git remote configured"71}72 73# 初始拉取74initial_pull() {75    cd "${WORK_DIR}"76    77    # 检查是否有提交78    if ! git rev-parse HEAD >/dev/null 2>&1; then79        log "No commits in local repo. Pulling from remote..."80        81        # 备份本地文件82        if [ "$(ls -A . 2>/dev/null | grep -v '^.git$')" ]; then83            log "Backing up local files..."84            mkdir -p /tmp/workspace-backup85            find . -maxdepth 1 ! -name '.git' ! -name '.' -exec cp -r {} /tmp/workspace-backup/ \;86        fi87        88        # 拉取远程89        git fetch origin "${GIT_BRANCH}" || true90        git checkout -b "${GIT_BRANCH}" || git checkout "${GIT_BRANCH}"91        git reset --hard "origin/${GIT_BRANCH}" 2>/dev/null || true92        93        # 恢复备份文件(如果有冲突,保留远程版本)94        if [ -d /tmp/workspace-backup ] && [ "$(ls -A /tmp/workspace-backup 2>/dev/null)" ]; then95            log "Restoring local files..."96            cp -r /tmp/workspace-backup/* . 2>/dev/null || true97            rm -rf /tmp/workspace-backup98        fi99    fi100}101 102# 推送变更103push_changes() {104    cd "${WORK_DIR}"105    106    # 检查是否有变更107    if [ -z "$(git status --porcelain)" ]; then108        log "No changes to push"109        return 0110    fi111    112    log "Pushing changes to remote..."113    114    # 添加所有变更115    git add -A116    117    # 排除敏感文件118    for pattern in ${SYNC_EXCLUDE}; do119        git reset HEAD "${pattern}" 2>/dev/null || true120    done121    122    # 生成提交信息123    CHANGES=$(git status --porcelain | head -20)124    COMMIT_MSG="${COMMIT_PREFIX} Auto-sync $(date '+%Y-%m-%d %H:%M:%S')125 126Changes:127${CHANGES}"128    129    # 提交130    git commit -m "${COMMIT_MSG}" || {131        log "Nothing to commit"132        return 0133    }134    135    # 拉取远程变更(rebase)136    git fetch origin "${GIT_BRANCH}" || true137    git rebase "origin/${GIT_BRANCH}" 2>/dev/null || {138        log "Rebase conflict detected. Creating backup and forcing push..."139        # 创建冲突备份140        git stash push -m "conflict-backup-$(date +%s)" 2>/dev/null || true141        git rebase --abort 2>/dev/null || true142        git reset --hard "origin/${GIT_BRANCH}"143        git stash pop 2>/dev/null || true144    }145    146    # 推送147    git push origin "${GIT_BRANCH}" || {148        error "Failed to push changes"149        return 1150    }151    152    log "Changes pushed successfully"153}154 155# 拉取变更156pull_changes() {157    cd "${WORK_DIR}"158    159    log "Pulling changes from remote..."160    161    # 获取远程变更162    git fetch origin "${GIT_BRANCH}" || return 1163    164    # 检查是否有新变更165    LOCAL=$(git rev-parse HEAD 2>/dev/null || echo "")166    REMOTE=$(git rev-parse "origin/${GIT_BRANCH}" 2>/dev/null || echo "")167    168    if [ "$LOCAL" = "$REMOTE" ]; then169        log "Remote is up to date"170        return 0171    fi172    173    # 保存本地变更174    if [ -n "$(git status --porcelain)" ]; then175        log "Stashing local changes..."176        git stash push -m "auto-stash-$(date +%s)"177    fi178    179    # 拉取180    git pull --rebase origin "${GIT_BRANCH}" || {181        error "Pull conflict detected"182        git rebase --abort 2>/dev/null || true183        return 1184    }185    186    # 恢复本地变更187    git stash pop 2>/dev/null || true188    189    log "Changes pulled successfully"190}191 192# 同步状态193sync_status() {194    cd "${WORK_DIR}"195    196    echo "=== Git Sync Status ==="197    echo "Repository: ${GIT_REPO_URL:-Not configured}"198    echo "Branch: ${GIT_BRANCH}"199    echo "Interval: ${GIT_SYNC_INTERVAL}s"200    echo ""201    202    if [ -d ".git" ]; then203        echo "Local commits:"204        git log --oneline -5 2>/dev/null || echo "No commits yet"205        echo ""206        echo "Working directory status:"207        git status --short 2>/dev/null || echo "Clean"208    else209        echo "Not a git repository"210    fi211}212 213# 主同步循环214main_loop() {215    log "Starting Git sync service..."216    log "Repository: ${GIT_REPO_URL}"217    log "Branch: ${GIT_BRANCH}"218    log "Interval: ${GIT_SYNC_INTERVAL}s"219    220    # 初始设置221    setup_remote222    initial_pull223    224    # 同步循环225    while true; do226        sleep "${GIT_SYNC_INTERVAL}"227        228        # 先拉取再推送229        pull_changes || true230        push_changes || true231    done232}233 234# 命令行接口235case "${1:-}" in236    push)237        check_git_config || exit 1238        setup_remote239        push_changes240        ;;241    pull)242        check_git_config || exit 1243        setup_remote244        pull_changes245        ;;246    status)247        sync_status248        ;;249    init)250        check_git_config || exit 1251        setup_remote252        initial_pull253        ;;254    *)255        if check_git_config; then256            main_loop257        else258            log "Git sync service not started due to missing configuration"259            # 保持进程运行但不执行同步260            tail -f /dev/null261        fi262        ;;263esac264