名称: 工作树状态检查 描述: 审计当前项目中的所有Git工作树。当用户询问工作树状态、哪些分支已合并、哪些有未提交更改,或哪些工作树可以安全清理时使用。
工作树状态检查
报告当前项目中每个Git工作树的状态,涵盖脏状态和合并状态。
何时使用
- 用户询问“哪些工作树可以清理?”
- 用户询问“我的工作树/分支状态如何?”
- 在批量清理工作树之前,以避免丢失未提交的工作
步骤
1. 拉取最新主分支(必须)
在进行任何状态检查之前,必须拉取最新主分支。否则,合并检测(包括祖先关系和内容差异)会产生过时结果,可能导致错误地认为分支未合并。
cd "$(git rev-parse --show-toplevel)" && git pull origin main
2. 收集工作树信息
PROJECT_DIR="$(git rev-parse --show-toplevel)"
for wt in $(git worktree list --porcelain | grep "^worktree " | sed 's/^worktree //' | grep -v "$PROJECT_DIR$"); do
branch=$(git -C "$wt" branch --show-current 2>/dev/null)
[ -z "$branch" ] && branch="(detached)"
name=$(basename "$wt")
# 是否有未提交更改?
if [ -z "$(git -C "$wt" status --short 2>/dev/null)" ]; then
dirty="clean"
else
dirty="DIRTY"
fi
# 是否已合并到origin/main?
# 注意:此项目仅使用压缩合并。`git merge-base --is-ancestor` 无法检测压缩合并的分支。对于显示“未合并”的分支,始终使用内容差异(步骤3)进行验证。
if [ "$branch" != "(detached)" ]; then
if git merge-base --is-ancestor "$branch" origin/main 2>/dev/null; then
merged="merged"
else
merged="not merged (verify with content diff)"
fi
else
merged="n/a"
fi
echo ""
echo "[$name] branch=$branch $dirty $merged"
if [ "$dirty" = "DIRTY" ]; then
git -C "$wt" status --short 2>/dev/null | sed 's/^/ /'
fi
done
3. 检测压缩合并分支(内容差异)
对于任何显示“未合并”的分支,检查分支更改是否已在主分支中。正确方法:
- 查找分支实际更改的文件(相对于合并基点)。
- 对于每个更改的文件,比较分支版本与主分支版本。 如果所有文件都相同,则分支被压缩合并。
⚠️ 不要使用 git diff origin/main <branch> — 这直接比较两个分支尖端,所以分支分叉后添加到主分支的提交会显示为虚假差异。
BRANCH="<branch>"
BASE=$(git merge-base origin/main "$BRANCH")
# 列出分支修改的文件
FILES=$(git diff --name-only "$BASE" "$BRANCH")
# 比较分支和当前主分支的每个文件
for f in $FILES; do
d=$(git diff "$BRANCH" origin/main -- "$f" | wc -l)
if [ "$d" != "0" ]; then
echo "❌ $f — 存在差异"
else
echo "✅ $f — 主分支中相同"
fi
done
# 所有 ✅ = 压缩合并
4. (可选)检查相关tmux会话
仅在 tmux 可用且相关时运行(例如,工作树由codex-worker或类似工具创建)。如不适用则跳过。
tmux ls 2>/dev/null | grep -E 'codex-worker|<other-pattern>' || true
5. 呈现结果
始终以Markdown表格呈现结果。 每个工作树必须作为一行。切勿使用缩写或纯文本摘要。
| 工作树 | 分支 | 未提交更改 | 是否合并 | 可清理? |
|---|---|---|---|---|
example-wt |
feat-foo |
✅ 干净 | ✅ 压缩合并 | ✅ |
another-wt |
fix-bar |
⚠️ 3个文件 | ❌ 未合并 | ❌ 有未提交更改 + 未合并 |
detached-wt |
(detached) | ⚠️ 14个文件 | n/a | ❌ 有未提交更改 |
列定义:
- 未提交更改:
✅ 干净或⚠️ N个文件 - 是否合并:
✅ 已合并/✅ 压缩合并(通过内容差异确认) /❌ 未合并/n/a - 可清理?:
✅仅当已合并(或压缩合并)且干净时
仅在相关时添加额外列(如tmux会话、备注)。
6. 清理(仅在用户要求时执行)
仅清理用户明确批准的工作树。对于每个:
NAME="<worktree-name>"
git worktree remove "/path/to/$NAME"
git branch -D "<branch>" # 仅在分支不再需要时