fix(assistant): 判定是不是存取庫交給 git 自己回答
原本看 .git 在不在。這台機器的工作目錄底下剛好有一個目錄的 .git 只剩 一個空的 info/,git 一句「not a git repository」——而掃描把它算成一個 存取庫,還印成「沒有 origin」。那個說法讀起來像「這個存取庫還沒接遠端」, 不像「這裡根本不是存取庫」,兩件事的處置完全不同。 改成由 git 回答,並核對它認定的頂層就是那個目錄:只問「是不是在工作樹裡」 不夠,git 會從那裡往上找,.git 壞掉時它會找到上一層的存取庫然後答「是」。 兩邊都解成實體路徑再比,掃描起點帶符號連結那一段時字串才對得上。 多一個 not_a_repo= 判定行與收尾計數,執行那一支照樣原樣轉出。 存取庫數從 19 個變 18 個。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -231,7 +231,7 @@ else
|
||||
esac
|
||||
# 掃描那一支的逐項判定行被導進暫存檔,所以外面看不到。原樣轉出來:被拒的那幾個存取庫是
|
||||
# 這一輪「掃到但沒交出去」的名單,那份名單不能只留在暫存檔裡。
|
||||
sed -n 's/^\(rejected=\|unnamed=\|excluded=\|skipped_link=\)/repo_scan_note=\1/p' \
|
||||
sed -n 's/^\(rejected=\|unnamed=\|excluded=\|skipped_link=\|not_a_repo=\)/repo_scan_note=\1/p' \
|
||||
"$TMPD/scan.out" "$TMPD/scan.err" 2>/dev/null
|
||||
fi
|
||||
N_REPOS=$(awk 'END{print NR+0}' "$REPOS")
|
||||
|
||||
+30
-4
@@ -16,6 +16,7 @@
|
||||
# 結束碼:
|
||||
# 0 掃到至少一個存取庫,而且每一個都對得出 REPO_{HASH}、路徑也都送得進殼
|
||||
# 1 掃到了,但有幾個對不出頁名或路徑被拒。可用的那幾個照印,被拒的逐行印在 rejected=
|
||||
# 有 .git 卻不被 git 認的那幾個也算在這一碼裡,印在 not_a_repo=
|
||||
# 2 用法錯誤:不認得的子命令或選項、選項缺值、--scan-root 不是絕對路徑、--depth 超出範圍
|
||||
# 3 掃描起點沒設定,或那條路徑不是存在的目錄——**什麼都沒掃**,不等於「這台機器沒有存取庫」
|
||||
# 4 掃過了,一個 git 存取庫都沒有
|
||||
@@ -183,7 +184,7 @@ sort -u -o "$CAND" "$CAND"
|
||||
|
||||
# --- 逐個判定 ---
|
||||
|
||||
N_REPO=0; N_REJ=0; N_UNNAMED=0; N_EXCL=0; N_LINK=0
|
||||
N_REPO=0; N_REJ=0; N_UNNAMED=0; N_EXCL=0; N_LINK=0; N_FAKE=0
|
||||
OUT="$TMPD/out.txt"
|
||||
: >"$OUT"
|
||||
|
||||
@@ -195,9 +196,32 @@ while IFS= read -r d; do
|
||||
emit "excluded=$d reason=在排除清單上"
|
||||
continue
|
||||
fi
|
||||
# .git 可能是目錄(一般存取庫),也可能是檔案(worktree 與子模組)。兩種都算存取庫。
|
||||
# .git 可能是目錄(一般存取庫),也可能是檔案(worktree 與子模組),所以先看它在不在,
|
||||
# 但**在不在只是初篩,不是判定**。
|
||||
[ -e "$d/.git" ] || continue
|
||||
|
||||
# 判定交給 git 自己。有 .git 不等於是存取庫:實測這台機器上有一個目錄底下的 .git 只剩
|
||||
# 一個空的 info/,git 一句「not a git repository」,而只看 .git 在不在的掃描把它算成
|
||||
# 一個存取庫、印成「沒有 origin」——那個說法讀起來像「這個存取庫還沒接遠端」,
|
||||
# 不像「這裡根本不是存取庫」。兩件事的處置完全不同。
|
||||
#
|
||||
# 只問「是不是在工作樹裡」不夠:git 會從這個目錄往上找,$d/.git 壞掉時它會找到上一層的
|
||||
# 存取庫然後回答「是」。所以要再核對它認定的頂層就是 $d 自己。兩邊都解成實體路徑再比,
|
||||
# 掃描起點帶符號連結那一段時字串才對得上。
|
||||
_top=$(git -C "$d" rev-parse --show-toplevel 2>/dev/null) || _top=''
|
||||
_dreal=$(CDPATH= cd -P -- "$d" 2>/dev/null && pwd -P) || _dreal=''
|
||||
_topreal=''
|
||||
[ -n "$_top" ] && { _topreal=$(CDPATH= cd -P -- "$_top" 2>/dev/null && pwd -P) || _topreal=''; }
|
||||
if [ -z "$_topreal" ] || [ "$_topreal" != "$_dreal" ]; then
|
||||
N_FAKE=$((N_FAKE + 1))
|
||||
if [ -z "$_top" ]; then
|
||||
emit "not_a_repo=$d reason=有 .git 但 git 自己不認,多半是刪剩的殘骸"
|
||||
else
|
||||
emit "not_a_repo=$d reason=有 .git 但 git 認定的頂層是 $_top,這裡不是存取庫的根"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$d" in
|
||||
*[!A-Za-z0-9/._-]*)
|
||||
N_REJ=$((N_REJ + 1))
|
||||
@@ -255,7 +279,7 @@ else
|
||||
done <"$OUT"
|
||||
fi
|
||||
|
||||
emit "scan_root=$SCAN_ROOT depth=$DEPTH repos=$N_REPO unnamed=$N_UNNAMED rejected=$N_REJ excluded=$N_EXCL skipped_links=$N_LINK"
|
||||
emit "scan_root=$SCAN_ROOT depth=$DEPTH repos=$N_REPO unnamed=$N_UNNAMED rejected=$N_REJ excluded=$N_EXCL skipped_links=$N_LINK not_a_repo=$N_FAKE"
|
||||
|
||||
case "$HASH_MODE" in
|
||||
sha1sum|shasum) note '找不到共用那一支 hash-id(jsc-gitea 的 tools/hash-id),這一輪的頁名改用本機的 SHA-1 算。兩者是同一條規則、值相同,只是少了一層共用;--root 餵對就會用共用那一支。' ;;
|
||||
@@ -267,7 +291,9 @@ esac
|
||||
if [ "$N_REPO" -eq 0 ]; then
|
||||
die 4 "掃過 $SCAN_ROOT 底下 $DEPTH 層,一個 git 存取庫都沒有。掃描起點指錯一層就會長這樣——工作目錄的版面是「一個存取庫一個子目錄」,指到某一個存取庫裡面就只剩它自己那一個,指到家目錄就一個都沒有。"
|
||||
fi
|
||||
if [ "$N_REJ" -gt 0 ] || [ "$N_UNNAMED" -gt 0 ]; then
|
||||
[ "$N_FAKE" -gt 0 ] && warn "有 $N_FAKE 個目錄底下有 .git 卻不被 git 認,逐個印在上面的 not_a_repo= 那幾行。那不是「還沒接遠端的存取庫」,是刪剩的殘骸或者不是存取庫的根——只看 .git 在不在的掃描會把它算成一個存取庫。"
|
||||
|
||||
if [ "$N_REJ" -gt 0 ] || [ "$N_UNNAMED" -gt 0 ] || [ "$N_FAKE" -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user