zhuyuan-ice-gl-zy001/BRIDGE/tools/zy-repo-sync.sh

87 lines
4.7 KiB
Shell
Executable file
Raw Permalink 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
# ═══ zy-repo-sync · 移动硬盘 git 仓库 → 京东服务器 Forgejo 在线仓库 ═══
# 冰朔 2026-09-01 令(瞄点000092轮):"给服务器上开发个啥,能让移动硬盘里的
# git仓库同步到远端服务器上去变成在线仓库"。服务器上的"啥"=Forgejo(guanghulab.com/code/);
# 本工具=把任意本地 git 仓库接上去:不存在则建(默认私有)、挂干净远端、令牌只在内存。
# 纪律(同 zy-push):令牌只从 macOS 钥匙串读,永不落盘、永不进日志、永不进仓库;
# 永不 force push;线上若分叉先 fetch 对齐,接不上就停等人处理。
# 超大仓库引导(>前置反代请求体限制,公网推会 HTTP 413):走 SSH 隧道直连京东 Forgejo 本体——
# ssh -f -N -L 13340:127.0.0.1:3340 jd-fd-primary
# git push http://x-access-token:<令牌>@localhost:13340/bingshuo/<仓库名>.git main (注意:隧道内路径无 /code/ 前缀)
# 推完 pkill -f "ssh.*13340"。之后增量推送走公网即可(体量小,前置代理可容)。
# 用法:zy-repo-sync.sh <仓库路径> <仓库名> [private|public]
# 例:zy-repo-sync.sh "/Volumes/JZAO/铸渊-ICE-GL-ZY001" zhuyuan-ice-gl-zy001 private
set -uo pipefail
REPO_PATH="${1:?用法: zy-repo-sync.sh <仓库路径> <仓库名> [private|public]}"
REPO_NAME="${2:?缺仓库名}"
VISIBILITY="${3:-private}"
API_BASE="https://guanghulab.com/code/api/v1"
REMOTE_PATH="guanghulab.com/code/bingshuo/${REPO_NAME}.git"
KC_SERVICE="zhuyuan-forgejo-token"
KC_ACCOUNT="bingshuo"
LOG="$HOME/Library/Logs/zhuyuan-repo-sync.log"
log() { printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >> "$LOG"; }
[ -d "$REPO_PATH/.git" ] || { echo "FAIL 不是git仓库: $REPO_PATH"; exit 1; }
cd "$REPO_PATH" || exit 1
BRANCH=$(git branch --show-current)
[ -n "$BRANCH" ] || { echo "FAIL 无当前分支( detached? )"; exit 1; }
TOKEN=$(security find-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" -w 2>/dev/null)
[ -n "${TOKEN:-}" ] || { echo "FAIL 钥匙串无 ${KC_SERVICE}/${KC_ACCOUNT}(先跑 zy-push-install.sh)"; exit 1; }
scrub() { sed "s|${TOKEN}|***|g"; }
trap 'unset TOKEN PUSH_URL' EXIT
# ── 1 · 仓库线上存在吗?不存在则建 ──────────────────────────
CODE=$(curl -s -m 15 -o /tmp/zrs-check.$$ -w "%{http_code}" \
-H "Authorization: token $TOKEN" "$API_BASE/repos/bingshuo/$REPO_NAME")
if [ "$CODE" = "404" ]; then
PRIV=$([ "$VISIBILITY" = "private" ] && echo true || echo false)
CODE=$(curl -s -m 20 -o /tmp/zrs-create.$$ -w "%{http_code}" \
-X POST -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
-d "{\"name\":\"$REPO_NAME\",\"private\":$PRIV,\"default_branch\":\"main\",\"auto_init\":false}" \
"$API_BASE/user/repos")
if [ "$CODE" != "201" ]; then
echo "FAIL 建仓失败 HTTP $CODE: $(head -c 300 /tmp/zrs-create.$$ | scrub)"; log "FAIL create $REPO_NAME HTTP $CODE"; exit 1
fi
echo "已建仓 bingshuo/$REPO_NAME ($VISIBILITY)"
elif [ "$CODE" != "200" ]; then
echo "FAIL 查仓异常 HTTP $CODE: $(head -c 200 /tmp/zrs-check.$$ | scrub)"; exit 1
else
echo "仓已存在 bingshuo/$REPO_NAME"
fi
rm -f /tmp/zrs-check.$$ /tmp/zrs-create.$$
# ── 2 · 挂干净远端(URL 不含令牌,可安全留在 .git/config)────
if git remote get-url origin >/dev/null 2>&1; then
git remote set-url origin "https://$REMOTE_PATH"
else
git remote add origin "https://$REMOTE_PATH"
fi
# ── 3 · 推(永不 force);线上已有历史则先 fetch 对齐 ────────
PUSH_URL="https://x-access-token:${TOKEN}@${REMOTE_PATH}"
REMOTE_HEAD=$(git ls-remote "$PUSH_URL" "refs/heads/$BRANCH" 2>/dev/null | awk '{print $1}')
if [ -n "$REMOTE_HEAD" ] && [ "$REMOTE_HEAD" != "$(git rev-parse HEAD)" ]; then
if ! git fetch -q "$PUSH_URL" "$BRANCH" 2>&1 | scrub; then
echo "FAIL fetch 失败(网络或令牌)"; log "FAIL fetch $REPO_NAME"; exit 1
fi
if git merge-base --is-ancestor FETCH_HEAD HEAD; then
: # 本地已包含线上历史,直接快进推
else
echo "FAIL 与线上分叉,需人工处理(不 force)"; log "DIVERGED $REPO_NAME"; exit 1
fi
fi
if git push -q "$PUSH_URL" "$BRANCH:$BRANCH" 2>&1 | scrub | head -3; then
NEW_HEAD=$(git ls-remote "$PUSH_URL" "refs/heads/$BRANCH" 2>/dev/null | awk '{print $1}')
if [ "$NEW_HEAD" = "$(git rev-parse HEAD)" ]; then
echo "PASS 已同步 $BRANCH $(git rev-parse --short HEAD) → bingshuo/${REPO_NAME}(线上备份在位)"
log "PASS $REPO_NAME $BRANCH $(git rev-parse --short HEAD)"
else
echo "FAIL 推后核验不一致"; log "FAIL verify $REPO_NAME"; exit 1
fi
else
echo "FAIL push 失败"; log "FAIL push $REPO_NAME"; exit 1
fi