Files
gitea/tools/repo-sync.sh
T
jiantw83andClaude Opus 5 36fc4de73c fix(gitea): 補齊稽核缺失並修掉護欄失效
What:依 jsc-meta:skill-check 的稽核結果修正技能與工具——補上每個步驟的可檢核完成條件、
把留在內文的標準輸入輸出流程下放 tools/、修正查表與退碼路由造成的誤判。

Why:稽核發現這些缺失會讓技能在實際執行時走錯分支或靜默通過。
完成條件缺漏是最常被違反的一項;退碼誤判與查表錯誤則會讓良性狀況被當成失敗。

How:逐項對照 references/guidelines.md 的審核檢查清單修正,新增的工具都有
documented exit codes,並以真實執行驗證每條路徑。

Who:jsc-meta:skill-check 例行稽核(2026-08-25)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 14:58:54 +08:00

81 lines
3.0 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.
#!/usr/bin/env sh
# repo-sync.sh — 把單一存取庫同步到本機。
# 用法: repo-sync.sh <owner>/<repo> [target-dir] # target-dir 預設為 <repo>
# 目錄不存在 → git clone(clone URL 取自 gitea.sh clone-url)
# 目錄已存在 → git fetch、切到基準分支、git pull --ff-only
# 有未提交變更 → 只回報 dirty 與基準分支,不動分支也不 pull
# 基準分支的唯一優先序(呼叫端不必再判斷,也不要自己再推導一次):
# 1. gitea.sh default-branch <owner>/<repo>(該分支要在遠端存在)
# 2. 查不到時依序取遠端的 develop、main、master
# 3. 都沒有 → failed no default branch
# 輸出: 恰好一行,cloned、updated、dirty {分支} 或 failed {原因}。
# 前三種 exit 0;failed exit 1。
# dirty 會把解析好的基準分支一起帶出來,呼叫端直接拿去當 PR 的 base。
set -u
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
gitea="$script_dir/gitea.sh"
fail() { # 原因壓成一行,避免呼叫端解析多行輸出
printf 'failed %s\n' "$(printf '%s' "$1" | tr '\n\r\t' ' ')"
exit 1
}
full="${1:-}"
[ -n "$full" ] || fail "usage: repo-sync.sh <owner>/<repo> [target-dir]"
case "$full" in
*/*/*|/*|*/) fail "not owner/repo: $full" ;;
*/*) ;;
*) fail "not owner/repo: $full" ;;
esac
repo="${full#*/}"
target="${2:-$repo}"
remote_has() { # 遠端是否有這個分支
git -C "$target" rev-parse --verify --quiet "refs/remotes/origin/$1" >/dev/null 2>&1
}
if [ ! -e "$target" ]; then
# clone URL 只收 stdout:把 stderr 併進來會讓任何雜訊變成網址的一部分
err=$(mktemp)
url=$("$gitea" clone-url "$full" 2>"$err") || url=''
if [ -z "$url" ]; then
reason=$(cat "$err"); rm -f "$err"
fail "clone-url failed for $full: ${reason:-no clone URL}"
fi
rm -f "$err"
out=$(git clone "$url" "$target" 2>&1) || fail "clone: $out"
printf 'cloned\n'
exit 0
fi
git -C "$target" rev-parse --git-dir >/dev/null 2>&1 || fail "$target is not a git repo"
dirty=0
[ -z "$(git -C "$target" status --porcelain 2>/dev/null)" ] || dirty=1
# dirty 的存取庫也要解析基準分支:呼叫端拿它當 PR 的 base,自己再推導一次就會
# 出現第二套優先序。fetch 只更新 refs,不動工作目錄,dirty 時照樣安全;但 dirty
# 時網路失敗不算致命,還是要把 dirty 回報出去,改用本機既有的 remote refs 判斷。
if ! out=$(git -C "$target" fetch --prune origin 2>&1); then
[ "$dirty" -eq 1 ] || fail "fetch: $out"
fi
branch=$("$gitea" default-branch "$full" 2>/dev/null) || branch=''
if [ -z "$branch" ] || ! remote_has "$branch"; then
branch=''
for b in develop main master; do
if remote_has "$b"; then branch="$b"; break; fi
done
fi
[ -n "$branch" ] || fail "no default branch"
if [ "$dirty" -eq 1 ]; then
printf 'dirty %s\n' "$branch"
exit 0
fi
out=$(git -C "$target" checkout "$branch" 2>&1) || fail "checkout $branch: $out"
out=$(git -C "$target" pull --ff-only origin "$branch" 2>&1) || fail "pull $branch: $out"
printf 'updated\n'