Files
FlClash/tool/worktrees.sh
T
chen08209 96fcb9ab5e chore(agents,tool): rebuild agent config, lint gates, CI, and release tooling
Rework .agents/, Claude/Codex config, CI workflows, lint gates and
lint-rule tests, and the release/changelog tooling. The 5% comment
density gate stays diff-scoped inside git hooks, where GIT_DIR outranks
the -C the gate uses to locate the repository. The tray icon generator
writes multi-size ICO files from the SVG sources into the per-platform
tray asset directories. The custom code-review subagents are gone: the
built-in /code-review never dispatched them, and the subagent model now
lives in a user-level setting outside the repository.

The Makefile, build_config.yaml and CI hand the Core and Helper builds to
the setup build hook, so the buildkit launchers go, and setup.dart
packages AppImage and rpm on arm64 with flutter_distributor pinned to the
fork tag that normalizes packaging permissions.

Changelog: skip
2026-09-10 12:42:52 +08:00

78 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'USAGE'
usage: tool/worktrees.sh list | prune [--force]
list Show every worktree with its owner tool and whether it has uncommitted changes.
prune Remove worktrees that are clean, detached or locked-by-nobody, and not the main checkout.
Dirty worktrees are listed and kept; pass --force to remove them as well.
USAGE
}
owner_of() {
case "$1" in
*/.claude/worktrees/*) echo claude ;;
*/.codex/worktrees/*) echo codex ;;
*/.gemini/*) echo gemini ;;
*) echo other ;;
esac
}
root="$(git rev-parse --show-toplevel)"
each_worktree() {
git -C "$root" worktree list --porcelain | awk '/^worktree /{print substr($0, 10)}'
}
is_locked() {
git -C "$root" worktree list --porcelain | awk -v p="$1" '$0=="worktree " p{f=1; next} /^worktree /{f=0} f && /^locked/{found=1} END{exit !found}'
}
state_of() {
local path="$1"
if [ ! -d "$path" ]; then
echo missing
elif [ -n "$(git -C "$path" status --porcelain 2>/dev/null)" ]; then
echo dirty
else
echo clean
fi
}
cmd="${1:-list}"
force=0
[ "${2:-}" = "--force" ] && force=1
case "$cmd" in
list)
printf '%-8s %-8s %s\n' OWNER STATE PATH
while IFS= read -r path; do
printf '%-8s %-8s %s\n' "$(owner_of "$path")" "$(state_of "$path")" "$path"
done < <(each_worktree)
;;
prune)
git -C "$root" worktree prune
while IFS= read -r path; do
[ "$path" = "$root" ] && continue
if is_locked "$path"; then
echo "keep (locked): $path"
continue
fi
state="$(state_of "$path")"
if [ "$state" = dirty ] && [ "$force" -eq 0 ]; then
echo "keep (dirty): $path"
continue
fi
git -C "$root" worktree remove --force "$path" && echo "removed: $path"
done < <(each_worktree)
git -C "$root" worktree prune
;;
*)
usage
exit 1
;;
esac