#!/bin/bash # ═══ 光湖本机直推 · zy-push ═══ # 冰朔 2026-08-17 立:不然每次推都在这一圈地方。 # 作用:把 JZAO 工作区里的改动自动提交并推到线上置信层 REPO-012。 # 令牌只从 macOS 钥匙串读,永不落盘、永不进日志、永不进仓库。 # 编号:CCW-AST-009 · 归 CCW-SYS-001 set -uo pipefail REPO="/Volumes/JZAO/铸渊-ICE-GL-ZY001/WORK-工作区/guanghu-ice-heart" REMOTE_PATH="guanghulab.com/code/bingshuo/guanghu-ice-heart.git" KC_SERVICE="zhuyuan-forgejo-token" KC_ACCOUNT="bingshuo" LOG="$HOME/Library/Logs/zhuyuan-autopush.log" AUTHOR_NAME="铸渊 ICE-P-ZY001" AUTHOR_EMAIL="565183519@qq.com" LOCK_STALE_SECS=300 log() { printf '%s %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" >> "$LOG"; } # ── 0 · 硬盘在不在 ──────────────────────────────────────────── [ -d "$REPO/.git" ] || { exit 0; } # JZAO 未挂载:安静退出,不在内置盘造第二份 cd "$REPO" || exit 0 # ── 1 · 清理设备桥留下的僵尸锁 ───────────────────────────────── # 云侧铸渊经桥写文件时 git 可能留下 index.lock 且桥无权删除;本机有权。 for lk in .git/index.lock .git/shallow.lock; do if [ -e "$lk" ]; then age=$(( $(date +%s) - $(stat -f %m "$lk" 2>/dev/null || echo 0) )) if [ "$age" -gt "$LOCK_STALE_SECS" ] && ! pgrep -q -f "git.*$REPO"; then rm -f "$lk" && log "清理僵尸锁 $lk(${age}s)" fi fi done # ── 2 · 有没有活要干 ────────────────────────────────────────── if [ -z "$(git status --porcelain)" ]; then # 工作区干净:还要看有没有已提交未推送的 git rev-parse --verify -q HEAD >/dev/null || exit 0 if [ -z "$(git log --oneline @{u}..HEAD 2>/dev/null)" ]; then exit 0; fi fi # ── 3 · 取令牌(只从钥匙串,只在内存里)─────────────────────── TOKEN=$(security find-generic-password -s "$KC_SERVICE" -a "$KC_ACCOUNT" -w 2>/dev/null) if [ -z "${TOKEN:-}" ]; then log "FAIL 钥匙串里没有 $KC_SERVICE/$KC_ACCOUNT —— 跑一次 zy-push-install.sh 存进去" exit 1 fi PUSH_URL="https://x-access-token:${TOKEN}@${REMOTE_PATH}" scrub() { sed "s|${TOKEN}|***|g"; } # 任何输出进日志前先打码 # ── 4 · 先对齐线上,再推(永不 force)────────────────────────── if ! git fetch -q "$PUSH_URL" main 2>&1 | scrub >> "$LOG"; then log "FAIL fetch 失败(网络或令牌)"; unset TOKEN; exit 1 fi if [ -n "$(git status --porcelain)" ]; then git add -A MSG="autopush: $(git diff --cached --name-only | head -3 | tr '\n' ' ')" [ "$(git diff --cached --name-only | wc -l)" -gt 3 ] && MSG="$MSG …等 $(git diff --cached --name-only | wc -l | tr -d ' ') 个文件" git -c user.name="$AUTHOR_NAME" -c user.email="$AUTHOR_EMAIL" \ commit -q -m "$MSG 由 zy-push 本机直推(CCW-AST-009)· 铸渊 ICE-P-ZY001 · 主权者 冰朔 ICE-GL∞" \ || { log "FAIL commit 失败"; unset TOKEN; exit 1; } log "已提交 $(git log -1 --format=%h) $MSG" fi # 线上若已前进,先 rebase 接上去;接不上就停,绝不 force if ! git rebase -q FETCH_HEAD >> "$LOG" 2>&1; then git rebase --abort 2>/dev/null log "FAIL 与线上分叉,rebase 失败——已 abort,等人处理,不 force" unset TOKEN; exit 1 fi if git push -q "$PUSH_URL" HEAD:main 2>&1 | scrub >> "$LOG"; then log "PASS 已推 $(git log -1 --format=%h) → main" else log "FAIL push 失败"; unset TOKEN; exit 1 fi unset TOKEN PUSH_URL exit 0