fix(mirror_sync): 修复大仓体积测量漏算松散对象 + 固化 tarball 路线
- PACK_KB 原先只取 size-pack,tarball 路线建的松散对象裸仓 size-pack=0 → 误判体积=0、跳过 source-only 降级、错标 full(orca 因此被误标)。 现合并 size-pack + size,松散对象也能正确触发 source-only。 - 新增 --tarball <url>:直接下载源码 tarball 绕过被封锁的 git 智能 HTTP 端点。 本环境 github.com 经沙箱代理 502 封死 git clone,故 github 上游自动派生 codeload URL 走 tarball(非 github 上游不受影响,仍走 git clone)。 - 回写档案时补 sync_note(之前 source-only 成功却留着 stale 的『暂未镜像』)。
This commit is contained in:
+61
-3
@@ -5,6 +5,9 @@
|
||||
# bash scripts/mirror_sync.sh --id ipollowork
|
||||
# bash scripts/mirror_sync.sh --id ipollowork --depth 200 # 超大仓只取近期历史
|
||||
# bash scripts/mirror_sync.sh --id orca --blobless # 大仓懒拉 blob,只走源码快照
|
||||
# bash scripts/mirror_sync.sh --id orca --tarball <url> # 直接下载 tarball 绕过 git 端点
|
||||
# 说明:github.com 在本环境经沙箱代理 502 封死 git clone,脚本会自动把 github
|
||||
# 上游改写为 codeload tarball 路线;非 github 上游不受影响。
|
||||
#
|
||||
# 可见性由档案的 business.license.redistributable 决定(L1/L2 → public,L3 → private)。
|
||||
# 这条规则不能手工绕过:把 source-available 项目公开镜像,等于替对方做了一次
|
||||
@@ -31,6 +34,10 @@ NO_FETCH="0"
|
||||
# 大仓(尤其 blob 占比高)可把传输量从整包几百 MB 砍到几十 MB,且具备"克隆成功即落盘、
|
||||
# 之后懒拉 blob 失败可重跑续传"的容错;代价是只能走源码快照(partial clone 不能按 mirror 推送)。
|
||||
BLOBLESS="0"
|
||||
# tarball 路线:直接下载上游源码 tarball(codeload.github.com 等),绕过被封锁的
|
||||
# git 智能 HTTP 端点。本环境 github.com 经沙箱代理 502 封死,git clone 永不可用,
|
||||
# 故 github 上游默认走 tarball(自动派生 codeload URL),得到的是无历史的源码快照。
|
||||
TARBALL=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
@@ -42,6 +49,7 @@ while [[ $# -gt 0 ]]; do
|
||||
--set-public) SET_PUBLIC="1"; shift;;
|
||||
--no-fetch) NO_FETCH="1"; shift;;
|
||||
--blobless) BLOBLESS="1"; shift;;
|
||||
--tarball) TARBALL="$2"; shift 2;;
|
||||
*) echo "未知参数: $1" >&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
@@ -109,6 +117,14 @@ EXCLUDE_COUNT=${#EXCLUDE_PATHS[@]}
|
||||
|
||||
[[ -z "${UPSTREAM}" ]] && { echo "档案缺少 mirror.upstream" >&2; exit 1; }
|
||||
|
||||
# github.com 在本环境经沙箱代理 502 封死 git 智能 HTTP 端点,git clone 永远失败。
|
||||
# 自动派生 codeload tarball URL(绕过 git 端点),github 上游默认走 tarball 路线。
|
||||
# 非 github 上游(gitea/gitlab 等)不受影响,仍走正常 git clone。
|
||||
if [[ -z "${TARBALL}" && "${UPSTREAM}" =~ ^https?://github\.com/([^/]+)/([^/]+?)(\.git)?/?$ ]]; then
|
||||
TARBALL="https://codeload.github.com/${BASH_REMATCH[1]}/${BASH_REMATCH[2]}/tar.gz/refs/heads/main"
|
||||
echo " 上游为 github.com(本环境 git 端点受限)→ 自动改用 tarball 路线: ${TARBALL}"
|
||||
fi
|
||||
|
||||
echo "==> 镜像 ${ID}"
|
||||
echo " 上游 : ${UPSTREAM}"
|
||||
echo " 目标 : ${ORG}/${REPO_NAME}"
|
||||
@@ -195,12 +211,51 @@ cleanup_broken() {
|
||||
}
|
||||
trap cleanup_broken EXIT
|
||||
|
||||
# 从 tarball 构建源码快照裸仓:下载 → 解包 → 剔除非源码素材 → 单提交 → 裸仓克隆。
|
||||
# 适用于 git 端点不可达(本环境 github.com 被 502 封死)或仅需最新源码快照的场景。
|
||||
build_from_tarball() {
|
||||
echo " 从 tarball 构建源码快照(绕过 git 端点)..."
|
||||
SOURCE_ONLY_FORCE="yes"
|
||||
rm -rf "${MIRROR_DIR}"
|
||||
local tmp
|
||||
tmp="$(mktemp -d)"
|
||||
local tarball="${tmp}/src.tar.gz"
|
||||
local ok=0
|
||||
for attempt in $(seq 1 8); do
|
||||
if curl -sSL -C - -o "${tarball}" "${TARBALL}"; then
|
||||
ok=1; break
|
||||
fi
|
||||
echo " ⚠ 第 ${attempt} 次下载失败,$(( attempt * 10 ))s 后重试 ..."
|
||||
sleep $(( attempt * 10 ))
|
||||
[[ ${attempt} -eq 8 ]] && { echo "tarball 下载八次均失败" >&2; exit 1; }
|
||||
done
|
||||
[[ ${ok} -eq 1 ]] || { echo "下载失败" >&2; exit 1; }
|
||||
echo " 解包并剔除非源码素材 ..."
|
||||
mkdir -p "${tmp}/src"
|
||||
tar -xzf "${tarball}" -C "${tmp}/src" --strip-components=1
|
||||
find "${tmp}/src" -type f \( \
|
||||
-iname '*.png' -o -iname '*.gif' -o -iname '*.jpg' -o -iname '*.jpeg' \
|
||||
-o -iname '*.webp' -o -iname '*.ico' -o -iname '*.mp4' -o -iname '*.mov' \
|
||||
-o -iname '*.webm' -o -iname '*.wav' -o -iname '*.mp3' -o -iname '*.glb' \
|
||||
-o -iname '*.ttf' -o -iname '*.woff' -o -iname '*.woff2' -o -iname '*.eot' \
|
||||
-o -iname '*.pdf' -o -iname '*.zip' \) -delete
|
||||
git -C "${tmp}/src" init -q
|
||||
( cd "${tmp}/src" && git add -A \
|
||||
&& git -c user.name='agent-radar' -c user.email='radar@local' \
|
||||
commit -q -m "源码快照 @ $(date +%F) (tarball source-only)" )
|
||||
git clone --bare "${tmp}/src" "${MIRROR_DIR}"
|
||||
rm -rf "${tmp}"
|
||||
echo " 已构建本地裸仓(源码快照,无历史)"
|
||||
}
|
||||
|
||||
if [[ -d "${MIRROR_DIR}" ]] && ! repo_ok; then
|
||||
echo " 清理上次中断的半成品裸仓 ..."
|
||||
rm -rf "${MIRROR_DIR}"
|
||||
fi
|
||||
|
||||
if [[ "${NO_FETCH}" == "1" ]]; then
|
||||
if [[ -n "${TARBALL}" ]]; then
|
||||
build_from_tarball
|
||||
elif [[ "${NO_FETCH}" == "1" ]]; then
|
||||
# 跳过上游更新,直接用本地裸仓生成快照。
|
||||
# 2026-09-02 需要这个:本地裸仓已是完整的,只想重跑一次快照(改了排除项),
|
||||
# 但 GitHub 恰好连不上("Empty reply from server"),脚本在 fetch 阶段就退出,
|
||||
@@ -295,8 +350,10 @@ P_ENC="$(/Users/figmarlite/.workbuddy/binaries/python/envs/default/bin/python -c
|
||||
# 所以推送前先量体积,超限则自动降级为「源码快照」:剔除图片/音视频/字体等
|
||||
# 非源码素材——这些内容通常占一半以上体积,却不是"跟踪源码"要看的东西。
|
||||
MAX_PUSH_MB="${MAX_PUSH_MB:-45}"
|
||||
PACK_KB="$(git -C "${MIRROR_DIR}" count-objects -v | awk '/^size-pack:/{print $2}')"
|
||||
PACK_MB=$(( PACK_KB / 1024 ))
|
||||
# 既算打包对象(size-pack)也算松散对象(size):tarball 路线建的裸仓是松散对象,
|
||||
# size-pack 为 0,不合并会误判体积=0、跳过 source-only 降级(orca 曾因此被错标 full)。
|
||||
PACK_KB="$(git -C "${MIRROR_DIR}" count-objects -v | awk '/^size-pack:/{sp=$2} /^size:/{sz=$2} END{print sp+sz}')"
|
||||
PACK_MB=$(( ${PACK_KB:-0} / 1024 ))
|
||||
# blobless 镜像只能走源码快照:partial clone 不能按 mirror 推送。
|
||||
[[ "${BLOBLESS}" == "1" ]] && SOURCE_ONLY_FORCE="yes"
|
||||
MIRROR_MODE="full"
|
||||
@@ -457,6 +514,7 @@ text = update_block(text, "mirror", {
|
||||
"gitea_repo": f"{'gitinbox'}/{sys.argv[3]}",
|
||||
"last_sync": today(),
|
||||
"mode": sys.argv[4],
|
||||
"sync_note": f"已于 {today()} 镜像({sys.argv[4]} 模式,由 mirror_sync.sh 自动回写)。",
|
||||
})
|
||||
p.write_text(text, encoding="utf-8")
|
||||
PY
|
||||
|
||||
Reference in New Issue
Block a user