@minonl/dia 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/cli.js +425 -22
- package/docs/index.md +1 -1
- package/docs/msg-collab-m1.md +29 -0
- package/docs/overview.md +6 -0
- package/docs/service-noun.md +113 -3
- package/package.json +1 -1
- package/packages/wt/bin/dia-wt +237 -94
- package/packages/wt/tests/adopt.test.sh +80 -154
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# adopt / doctor / gate 回归测试(2026-11-
|
|
3
|
-
# 覆盖:dry-run 计划、apply 幂等、check 通过、主 checkout 守卫、doctor、revert。
|
|
2
|
+
# adopt / doctor / gate 回归测试(2026-11-06:每仓本地钩子 + simple-git-hooks RC)
|
|
4
3
|
set -uo pipefail
|
|
5
4
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
5
|
WT="$HERE/../bin/dia-wt"
|
|
@@ -8,26 +7,31 @@ TD="$(mktemp -d)"; trap 'rm -rf "$TD"' EXIT
|
|
|
8
7
|
PASS=0; FAIL=0
|
|
9
8
|
ok(){ echo " ✓ $1"; PASS=$((PASS+1)); }; bad(){ echo " ✗ $1"; FAIL=$((FAIL+1)); }
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
# 隔离 HOME / 全局 git 配置 / 数据根 / shell rc(避免污染真实机器)
|
|
11
|
+
export HOME="$TD/home"; mkdir -p "$HOME"
|
|
12
|
+
export GIT_CONFIG_GLOBAL="$TD/gitconfig"; : > "$GIT_CONFIG_GLOBAL"
|
|
13
|
+
export GIT_CONFIG_NOSYSTEM=1
|
|
14
|
+
export DIA_ROOT="$TD/dia"
|
|
15
|
+
export DIA_WT_SHELL_RC="$HOME/.zshenv"
|
|
14
16
|
|
|
17
|
+
mk_repo(){ local r="$1"; mkdir -p "$r"; git -C "$r" init -q -b main; git -C "$r" config user.email t@example.com; git -C "$r" config user.name t; echo a > "$r/a.txt"; git -C "$r" add -A; git -C "$r" commit -qm init; }
|
|
18
|
+
|
|
19
|
+
R="$TD/repo"; mk_repo "$R"
|
|
15
20
|
out="$(bash "$WT" adopt "$R" --json)"
|
|
16
21
|
printf '%s' "$out" | grep -q '"defaultBranch":"main"' && ok "dry-run 识别默认分支" || bad "dry-run: $out"
|
|
17
22
|
[ ! -f "$R/.git/dia/config.json" ] && ok "dry-run 不落盘" || bad "dry-run 落盘了"
|
|
18
23
|
|
|
19
24
|
bash "$WT" adopt "$R" --apply >/dev/null 2>&1 || bad "apply 失败"
|
|
20
25
|
[ -f "$R/.git/dia/config.json" ] && ok "config 已写" || bad "缺 config"
|
|
21
|
-
hp="$(git -C "$R" config --get core.hooksPath)"
|
|
22
|
-
case "$hp" in
|
|
23
|
-
[ -x "$R/.git/dia/hooks
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
hp="$(git -C "$R" config --local --get core.hooksPath)"
|
|
27
|
+
case "$hp" in */repo/.git/dia/hooks) ok "仓库本地 hooksPath 指向 dia 目录" ;; *) bad "hooksPath=$hp" ;; esac
|
|
28
|
+
for h in pre-commit pre-push post-checkout; do [ -x "$R/.git/dia/hooks/$h" ] || bad "缺 $h"; done
|
|
29
|
+
ok "三个钩子可执行"
|
|
30
|
+
python3 -c 'import json,sys;d=json.load(open(sys.argv[1]));sys.exit(0 if d.get("hooksManager")=="local" else 1)' "$R/.git/dia/config.json" \
|
|
31
|
+
&& ok "config 记录 hooksManager=local" || bad "hooksManager 未记录"
|
|
32
|
+
[ -z "$(git config --global --get core.hooksPath 2>/dev/null || true)" ] && ok "未写全局 git 配置" || bad "仍写了全局 hooksPath"
|
|
33
|
+
|
|
34
|
+
bash "$WT" adopt "$R" --apply >/dev/null 2>&1 && ok "重复 apply 幂等" || bad "重复 apply 失败"
|
|
31
35
|
bash "$WT" adopt "$R" --check >/dev/null 2>&1 && ok "check 通过" || bad "check 失败"
|
|
32
36
|
bash "$WT" doctor "$R" >/dev/null 2>&1 && ok "doctor 通过" || bad "doctor 失败"
|
|
33
37
|
|
|
@@ -35,155 +39,77 @@ echo b > "$R/b.txt"; git -C "$R" add b.txt
|
|
|
35
39
|
if git -C "$R" commit -qm should-block 2>/dev/null; then bad "主 checkout main 提交未被拦截"; else ok "主 checkout main 提交被拦截"; fi
|
|
36
40
|
git -C "$R" reset -q
|
|
37
41
|
|
|
38
|
-
#
|
|
42
|
+
# 链式:仓库自己的 .git/hooks/pre-commit 仍要执行
|
|
43
|
+
printf '#!/bin/sh\necho chained >> "$(git rev-parse --show-toplevel)/chain.log"\n' > "$R/.git/hooks/pre-commit"; chmod +x "$R/.git/hooks/pre-commit"
|
|
44
|
+
git -C "$R" worktree add -q -b feat/y "$TD/repo-worktree--y" main
|
|
45
|
+
echo c > "$TD/repo-worktree--y/c.txt"; git -C "$TD/repo-worktree--y" add c.txt
|
|
46
|
+
git -C "$TD/repo-worktree--y" commit -qm feat-y >/dev/null 2>&1
|
|
47
|
+
[ -f "$TD/repo-worktree--y/chain.log" ] && ok "仓库自己的钩子被链式执行" || bad "仓库钩子未执行"
|
|
48
|
+
rm -f "$TD/repo-worktree--y/chain.log"
|
|
49
|
+
|
|
50
|
+
# simple-git-hooks 仓:走 RC 注入,不碰仓内文件与 .git/hooks
|
|
51
|
+
RN="$TD/npmrepo"; mk_repo "$RN"
|
|
52
|
+
printf '{"name":"r","devDependencies":{"simple-git-hooks":"^2.11.1"},"simple-git-hooks":{"pre-commit":"npx lint-staged"}}\n' > "$RN/package.json"
|
|
53
|
+
git -C "$RN" add -A; git -C "$RN" commit -qm pkg
|
|
54
|
+
before="$(md5 -q "$RN/package.json" 2>/dev/null || md5sum "$RN/package.json" | cut -d' ' -f1)"
|
|
55
|
+
bash "$WT" adopt "$RN" --apply >/dev/null 2>&1 || bad "npm 仓 adopt 失败"
|
|
56
|
+
after="$(md5 -q "$RN/package.json" 2>/dev/null || md5sum "$RN/package.json" | cut -d' ' -f1)"
|
|
57
|
+
[ "$before" = "$after" ] && ok "不修改仓库 package.json" || bad "package.json 被改动"
|
|
58
|
+
[ -z "$(git -C "$RN" config --local --get core.hooksPath || true)" ] && ok "不占用仓库 hooksPath(交给管理器)" || bad "仍设置了 hooksPath"
|
|
59
|
+
[ -f "$DIA_ROOT/hooks/simple-git-hooks-rc.sh" ] && ok "写入 simple-git-hooks RC" || bad "缺 RC 文件"
|
|
60
|
+
grep -q "SIMPLE_GIT_HOOKS_RC" "$HOME/.zshenv" 2>/dev/null && ok "shell rc 注入 SIMPLE_GIT_HOOKS_RC" || bad "未注入环境变量"
|
|
61
|
+
bash "$WT" doctor "$RN" >/dev/null 2>&1 && ok "npm 仓 doctor 通过" || bad "npm 仓 doctor 失败"
|
|
62
|
+
(cd "$RN" && DIA_WT_GUARD_PROBE=1 bash "$WT" guard pre-commit >/dev/null 2>&1) && bad "guard 未拦截 main 提交" || ok "guard 拦截 main 提交"
|
|
63
|
+
|
|
64
|
+
# 全局配置残留检查:旧版全局钩子目录 → doctor FAIL
|
|
65
|
+
LEGACY="$TD/legacy-hooks"; mkdir -p "$LEGACY"
|
|
66
|
+
printf '#!/usr/bin/env bash\n# dia-wt guard(旧)\nexit 0\n' > "$LEGACY/pre-commit"; chmod +x "$LEGACY/pre-commit"
|
|
67
|
+
git config --global core.hooksPath "$LEGACY"
|
|
68
|
+
bash "$WT" doctor "$R" >/tmp/d20.log 2>&1; grep -q "D20" /tmp/d20.log && ok "doctor 报全局钩子残留" || bad "doctor 未报全局残留: $(head -3 /tmp/d20.log | tr "\n" " ")"
|
|
69
|
+
git config --global --unset core.hooksPath
|
|
70
|
+
|
|
71
|
+
# 未 adopt 的仓不受影响
|
|
72
|
+
R3="$TD/repo3"; mk_repo "$R3"; echo z > "$R3/z.txt"; git -C "$R3" add -A
|
|
73
|
+
git -C "$R3" commit -qm ok >/dev/null 2>&1 && ok "未 adopt 仓不受守卫影响" || bad "未 adopt 仓被误拦"
|
|
74
|
+
|
|
75
|
+
# 敏感扫描(worktree push)
|
|
39
76
|
BR="$TD/remote.git"; git init -q --bare "$BR"
|
|
40
77
|
git -C "$R" remote add origin "$BR" 2>/dev/null || true
|
|
41
78
|
git --git-dir="$BR" fetch -q "$R" main:main 2>/dev/null || true
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
git -C "$TD/
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
git -C "$TD/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
git -C "$TD/wt" add -A && git -C "$TD/wt" commit -qm vars
|
|
53
|
-
git -C "$TD/wt" push -q origin feat/scan 2>/dev/null && ok "相对片段 home/ 不误报" || bad "相对片段被误判为敏感路径"
|
|
54
|
-
|
|
55
|
-
bash "$WT" adopt "$R" --revert >/dev/null 2>&1 || bad "revert 失败"
|
|
56
|
-
[ -z "$(git -C "$R" config --get core.hooksPath || true)" ] && ok "revert 还原 hooksPath" || bad "revert 未还原"
|
|
57
|
-
[ ! -d "$R/.git/dia" ] && ok "revert 删除 dia 目录" || bad "dia 目录残留"
|
|
58
|
-
|
|
59
|
-
# ── 原 hooksPath 保留 + 二次 apply 不改写 hooksPrevious(review P2-7)──────────
|
|
60
|
-
R2="$TD/repo2"; mkdir -p "$R2" "$TD/orighooks"; git -C "$R2" init -q -b main
|
|
61
|
-
git -C "$R2" config user.email t@example.com; git -C "$R2" config user.name t
|
|
62
|
-
echo a > "$R2/a.txt"; git -C "$R2" add -A; git -C "$R2" commit -qm init
|
|
63
|
-
printf '#!/bin/sh\nexit 0\n' > "$TD/orighooks/pre-commit"; chmod +x "$TD/orighooks/pre-commit"
|
|
64
|
-
git -C "$R2" config --local core.hooksPath "$TD/orighooks"
|
|
65
|
-
bash "$WT" adopt "$R2" --apply >/dev/null 2>&1 || bad "R2 apply 失败"
|
|
66
|
-
hp1="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1])).get("hooksPrevious") or "")' "$R2/.git/dia/config.json")"
|
|
67
|
-
[ "$hp1" = "$TD/orighooks" ] && ok "首次 apply 记录 hooksPrevious" || bad "hooksPrevious=$hp1"
|
|
68
|
-
bash "$WT" adopt "$R2" --apply >/dev/null 2>&1
|
|
69
|
-
hp2="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1])).get("hooksPrevious") or "")' "$R2/.git/dia/config.json")"
|
|
70
|
-
[ "$hp2" = "$TD/orighooks" ] && ok "二次 apply 不覆盖 hooksPrevious" || bad "hooksPrevious 被改成 $hp2"
|
|
71
|
-
bash "$WT" adopt "$R2" --revert >/dev/null 2>&1 || bad "R2 revert 失败"
|
|
72
|
-
[ "$(git -C "$R2" config --get core.hooksPath)" = "$TD/orighooks" ] && ok "revert 还原原 hooksPath" || bad "revert 未还原原 hooksPath"
|
|
73
|
-
# hooksPath 被第三方改动 → revert 拒绝(不抢配置)
|
|
74
|
-
bash "$WT" adopt "$R2" --apply >/dev/null 2>&1
|
|
75
|
-
git -C "$R2" config --local core.hooksPath "$TD/orighooks"
|
|
76
|
-
if bash "$WT" adopt "$R2" --revert >/dev/null 2>&1; then bad "hooksPath 被改动后 revert 仍执行"; else ok "hooksPath 被改动后 revert 拒绝"; fi
|
|
77
|
-
[ -f "$R2/.git/dia/config.json" ] && ok "拒绝 revert 时保留 config 备份" || bad "拒绝 revert 却删了 config"
|
|
78
|
-
git -C "$R2" config --local core.hooksPath "$R2/.git/dia/hooks"; bash "$WT" adopt "$R2" --revert >/dev/null 2>&1
|
|
79
|
-
|
|
80
|
-
# ── 自定义默认分支受保护(review P1-1 + P1-2)────────────────────────────────
|
|
81
|
-
R3="$TD/repo3"; mkdir -p "$R3"; git -C "$R3" init -q -b trunk
|
|
82
|
-
git -C "$R3" config user.email t@example.com; git -C "$R3" config user.name t
|
|
83
|
-
echo a > "$R3/a.txt"; git -C "$R3" add -A; git -C "$R3" commit -qm init
|
|
84
|
-
bash "$WT" adopt "$R3" --apply --default-branch trunk >/dev/null 2>&1 || bad "自定义分支 apply 失败"
|
|
85
|
-
bash "$WT" adopt "$R3" --check >/dev/null 2>&1 && ok "自定义默认分支 check 通过" || bad "自定义默认分支 check 失败"
|
|
86
|
-
bash "$WT" doctor "$R3" >/dev/null 2>&1 && ok "自定义默认分支 doctor 通过" || bad "自定义默认分支 doctor 失败"
|
|
87
|
-
echo b > "$R3/b.txt"; git -C "$R3" add b.txt
|
|
88
|
-
if git -C "$R3" commit -qm should-block 2>/dev/null; then bad "trunk 提交未被拦截"; else ok "自定义默认分支 trunk 提交被拦截"; fi
|
|
89
|
-
git -C "$R3" reset -q
|
|
90
|
-
|
|
91
|
-
# ── doctor:未 adopt / 无参数(review P1-4)──────────────────────────────────
|
|
92
|
-
bash "$WT" doctor "$R3" >/dev/null 2>&1 || true
|
|
93
|
-
R4="$TD/repo4"; mkdir -p "$R4"; git -C "$R4" init -q -b main
|
|
94
|
-
git -C "$R4" config user.email t@example.com; git -C "$R4" config user.name t
|
|
95
|
-
echo a > "$R4/a.txt"; git -C "$R4" add -A; git -C "$R4" commit -qm init
|
|
96
|
-
if bash "$WT" doctor "$R4" >/dev/null 2>&1; then bad "未 adopt 的仓 doctor 误报通过"; else ok "未 adopt 的仓 doctor 失败"; fi
|
|
97
|
-
bash "$WT" doctor >/dev/null 2>&1; [ $? = 2 ] && ok "doctor 无参数 exit 2" || bad "doctor 无参数未 exit 2"
|
|
98
|
-
|
|
99
|
-
# ── pre-push 守卫(主 checkout 拒绝 / worktree 放行)──────────────────────────
|
|
100
|
-
R5="$TD/repo5"; ORIGIN5="$TD/origin5.git"; git init -q --bare "$ORIGIN5"
|
|
101
|
-
mkdir -p "$R5"; git -C "$R5" init -q -b main
|
|
102
|
-
git -C "$R5" config user.email t@example.com; git -C "$R5" config user.name t
|
|
103
|
-
echo a > "$R5/a.txt"; git -C "$R5" add -A; git -C "$R5" commit -qm init
|
|
104
|
-
git -C "$R5" remote add origin "$ORIGIN5"; git -C "$R5" push -q origin main
|
|
105
|
-
git -C "$R5" fetch -q origin
|
|
106
|
-
git -C "$R5" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main
|
|
107
|
-
bash "$WT" adopt "$R5" --apply >/dev/null 2>&1 || bad "R5 apply 失败"
|
|
108
|
-
# 主 checkout 的 pre-push 拒绝的是「从这里发起的任何 push」(含 feature 分支),不需要脏提交
|
|
109
|
-
git -C "$R5" branch feat/push-probe origin/main
|
|
110
|
-
if git -C "$R5" push origin feat/push-probe >/dev/null 2>&1; then bad "主 checkout push 未被拦截"; else ok "主 checkout push 被拦截"; fi
|
|
111
|
-
git -C "$R5" branch -D feat/push-probe >/dev/null 2>&1 || true
|
|
112
|
-
git -C "$R5" worktree add -q -b feat/x "$TD/repo5-worktree--x" main
|
|
113
|
-
echo b > "$TD/repo5-worktree--x/b.txt"; git -C "$TD/repo5-worktree--x" add b.txt
|
|
114
|
-
git -C "$TD/repo5-worktree--x" commit -qm feat-x 2>/dev/null
|
|
115
|
-
if git -C "$TD/repo5-worktree--x" push -q origin feat/x >/dev/null 2>&1; then ok "worktree push 放行"; else bad "worktree push 被误拦"; fi
|
|
116
|
-
|
|
117
|
-
# ── template 生效(P2-6):adopt 后 create 按 config.template 推导路径 ─────────
|
|
118
|
-
out="$(bash "$WT" create "$R5" t1 --dry-run 2>&1 || true)"
|
|
119
|
-
printf '%s' "$out" | grep -q "repo5-worktree--t1" && ok "默认模板 create 路径" || bad "默认模板 create: $out"
|
|
120
|
-
bash "$WT" adopt "$R5" --apply --template '{{parent}}/{{repo}}.wt.{{feature}}' >/dev/null 2>&1 || bad "template apply 失败"
|
|
121
|
-
out="$(bash "$WT" create "$R5" t1 --dry-run 2>&1 || true)"
|
|
122
|
-
printf '%s' "$out" | grep -q "repo5.wt.t1" && ok "自定义模板 create 路径生效" || bad "自定义模板: $out"
|
|
123
|
-
bash "$WT" adopt "$R5" --apply >/dev/null 2>&1
|
|
124
|
-
|
|
125
|
-
# ── 过期 origin/HEAD(远端分支已删)不误判默认分支 ──────────────────────────
|
|
126
|
-
R6="$TD/repo6"; mkdir -p "$R6"; git -C "$R6" init -q -b main
|
|
127
|
-
git -C "$R6" config user.email t@example.com; git -C "$R6" config user.name t
|
|
128
|
-
echo a > "$R6/a.txt"; git -C "$R6" add -A; git -C "$R6" commit -qm init
|
|
129
|
-
git -C "$R6" symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/gone
|
|
130
|
-
out="$(bash "$WT" adopt "$R6" --json)"
|
|
131
|
-
printf '%s' "$out" | grep -q '"defaultBranch":"main"' && ok "过期 origin/HEAD 回落到 main" || bad "过期 origin/HEAD: $out"
|
|
132
|
-
|
|
133
|
-
# ── 钩子链:原 hooksPath(.githooks / husky)不被吞掉 ─────────────────────────
|
|
134
|
-
R7="$TD/repo7"; mkdir -p "$R7/.githooks"; git -C "$R7" init -q -b main
|
|
135
|
-
git -C "$R7" config user.email t@example.com; git -C "$R7" config user.name t
|
|
136
|
-
printf '#!/bin/sh\necho chained >> "$(git rev-parse --show-toplevel)/chain.log"\n' > "$R7/.githooks/pre-commit"
|
|
137
|
-
chmod +x "$R7/.githooks/pre-commit"
|
|
138
|
-
echo a > "$R7/a.txt"; git -C "$R7" add -A; git -C "$R7" commit -qm init
|
|
139
|
-
git -C "$R7" config --local core.hooksPath .githooks
|
|
140
|
-
bash "$WT" adopt "$R7" --apply >/dev/null 2>&1 || bad "R7 apply 失败"
|
|
141
|
-
python3 -c 'import json,sys;d=json.load(open(sys.argv[1]));sys.exit(0 if d.get("hooksChain")==".githooks" else 1)' "$R7/.git/dia/config.json" \
|
|
142
|
-
&& ok "config 记录 hooksChain" || bad "hooksChain 未记录"
|
|
143
|
-
git -C "$R7" worktree add -q -b feat/y "$TD/repo7-worktree--y" main
|
|
144
|
-
echo b > "$TD/repo7-worktree--y/b.txt"; git -C "$TD/repo7-worktree--y" add b.txt
|
|
145
|
-
git -C "$TD/repo7-worktree--y" commit -qm feat-y >/dev/null 2>&1
|
|
146
|
-
[ -f "$TD/repo7-worktree--y/chain.log" ] && ok "原 pre-commit 被链式执行" || bad "原 pre-commit 未执行(钩子被吞)"
|
|
147
|
-
bash "$WT" adopt "$R7" --revert >/dev/null 2>&1
|
|
148
|
-
[ "$(git -C "$R7" config --get core.hooksPath)" = ".githooks" ] && ok "revert 还原原 hooksPath(相对)" || bad "revert 未还原 .githooks"
|
|
149
|
-
|
|
150
|
-
# ── adopt --all:批量主 checkout,跳过 worktree 目录 ─────────────────────────
|
|
79
|
+
git -C "$R" fetch -q origin 2>/dev/null || true
|
|
80
|
+
BAD="$(printf '/%s/alice/secret' Users)"; echo "$BAD" > "$TD/repo-worktree--y/bad.txt"
|
|
81
|
+
git -C "$TD/repo-worktree--y" add bad.txt; git -C "$TD/repo-worktree--y" commit -qm bad >/dev/null 2>&1
|
|
82
|
+
if git -C "$TD/repo-worktree--y" push -q origin feat/y 2>/dev/null; then bad "敏感推送未被拦截"; else ok "敏感推送被拦截"; fi
|
|
83
|
+
git -C "$TD/repo-worktree--y" reset -q --hard HEAD~1
|
|
84
|
+
printf 'path=$TD/home/kits/dia.json\n' > "$TD/repo-worktree--y/vars.txt"
|
|
85
|
+
git -C "$TD/repo-worktree--y" add vars.txt && git -C "$TD/repo-worktree--y" commit -qm vars >/dev/null 2>&1
|
|
86
|
+
git -C "$TD/repo-worktree--y" push -q origin feat/y 2>/dev/null && ok "相对片段 home/ 不误报" || bad "相对片段被误判"
|
|
87
|
+
|
|
88
|
+
# adopt --all
|
|
151
89
|
AR="$TD/allroot"; mkdir -p "$AR/a" "$AR/b"
|
|
152
|
-
for r in a b; do
|
|
153
|
-
git -C "$AR/$r" init -q -b main
|
|
154
|
-
git -C "$AR/$r" config user.email t@example.com; git -C "$AR/$r" config user.name t
|
|
155
|
-
echo x > "$AR/$r/x.txt"; git -C "$AR/$r" add -A; git -C "$AR/$r" commit -qm init
|
|
156
|
-
done
|
|
90
|
+
for r in a b; do mk_repo "$AR/$r"; done
|
|
157
91
|
git -C "$AR/a" worktree add -q -b feat/w "$AR/a-worktree--w" main
|
|
158
|
-
out="$(DIA_WT_REPOS_ROOT="$AR"
|
|
92
|
+
out="$(DIA_WT_REPOS_ROOT="$AR" bash "$WT" adopt --all --apply --json 2>&1)"
|
|
159
93
|
printf '%s' "$out" | grep -q '"repos":2,"ok":2,"fail":0' && ok "adopt --all 覆盖 2 个主 checkout" || bad "adopt --all: $out"
|
|
160
|
-
for r in a b; do
|
|
161
|
-
[ -n "$(git -C "$AR/$r" config --get core.hooksPath || true)" ] && ok "adopt --all: $r 已配 hooksPath" || bad "adopt --all: $r 未配置"
|
|
162
|
-
done
|
|
163
94
|
[ ! -d "$AR/a-worktree--w/.git/dia" ] && ok "adopt --all 跳过 worktree 目录" || bad "adopt --all 误改 worktree"
|
|
164
|
-
out="$(DIA_WT_REPOS_ROOT="$AR"
|
|
165
|
-
printf '%s' "$out" | grep -q "$AR/a" && ok "doctor --all
|
|
166
|
-
DIA_WT_REPOS_ROOT="$TD/empty-root"
|
|
95
|
+
out="$(DIA_WT_REPOS_ROOT="$AR" bash "$WT" doctor --all --json 2>/dev/null)"
|
|
96
|
+
printf '%s' "$out" | grep -q "$AR/a" && ok "doctor --all 覆盖自定义仓根" || bad "doctor --all 未覆盖"
|
|
97
|
+
DIA_WT_REPOS_ROOT="$TD/empty-root" bash "$WT" adopt --all >/dev/null 2>&1
|
|
167
98
|
[ $? = 2 ] && ok "adopt --all 空结果 exit 2" || bad "adopt --all 空结果未 exit 2"
|
|
168
99
|
|
|
169
|
-
#
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
if bash "$WT" doctor "$R8" >/dev/null 2>&1; then bad "钩子被覆盖后 doctor 仍通过"; else ok "钩子被覆盖后 doctor 报失败"; fi
|
|
177
|
-
bash "$WT" doctor "$R8" --fix >/dev/null 2>&1 || bad "doctor --fix 失败"
|
|
178
|
-
bash "$WT" doctor "$R8" >/dev/null 2>&1 && ok "doctor --fix 后恢复 ok" || bad "doctor --fix 后仍失败"
|
|
179
|
-
[ -x "$R8/.git/dia/hooks/post-checkout" ] && ok "doctor --fix 补回 post-checkout" || bad "post-checkout 未补回"
|
|
100
|
+
# gate
|
|
101
|
+
rm -f "$TD/repo-worktree--y/chain.log"
|
|
102
|
+
if bash "$WT" gate "$R" y >/tmp/gate.log 2>&1; then ok "gate 成功"; else bad "gate 失败: $(tail -2 /tmp/gate.log | tr '\n' ' ')"; fi
|
|
103
|
+
if bash "$WT" gate "$R" yb >/dev/null 2>&1; then bad "gate 子串误匹配"; else ok "gate 精确匹配 feature"; fi
|
|
104
|
+
echo dirty >> "$TD/repo-worktree--y/c.txt"
|
|
105
|
+
if bash "$WT" gate "$R" y >/dev/null 2>&1; then bad "worktree 脏时 gate 通过"; else ok "worktree 脏时 gate 失败"; fi
|
|
106
|
+
git -C "$TD/repo-worktree--y" checkout -q -- c.txt
|
|
180
107
|
|
|
181
|
-
#
|
|
182
|
-
bash "$WT"
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
git -C "$TD/repo5-worktree--x" checkout -q -- b.txt
|
|
108
|
+
# revert
|
|
109
|
+
bash "$WT" adopt "$R" --revert >/dev/null 2>&1 || bad "revert 失败"
|
|
110
|
+
[ ! -f "$R/.git/dia/config.json" ] && ok "revert 删除本仓配置" || bad "配置残留"
|
|
111
|
+
[ -z "$(git -C "$R" config --local --get core.hooksPath || true)" ] && ok "revert 还原本地 hooksPath" || bad "hooksPath 未还原"
|
|
112
|
+
git -C "$R" worktree remove --force "$TD/repo-worktree--y" >/dev/null 2>&1 || true
|
|
187
113
|
|
|
188
114
|
echo; echo "── PASS $PASS · FAIL $FAIL ──"
|
|
189
115
|
[ "$FAIL" = 0 ]
|