chore: 新增同步变更到 air-cargo 项目的 sync-air-cargo skill
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
98
.claude/skills/sync-air-cargo/scripts/sync.sh
Executable file
98
.claude/skills/sync-air-cargo/scripts/sync.sh
Executable file
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
# 将 SOURCE_DIR 中未提交的变更(修改/新增/删除)以 cp/rm 的方式同步到 TARGET_DIR。
|
||||
# 两个目录是同一份项目源码的独立 git 仓库副本,只做文件级复制/删除,不做任何内容编辑。
|
||||
set -euo pipefail
|
||||
|
||||
SOURCE_DIR="${1:-$(pwd)}"
|
||||
SOURCE_DIR="$(cd "$SOURCE_DIR" && pwd)"
|
||||
TARGET_DIR="${2:-$(dirname "$SOURCE_DIR")/air-cargo}"
|
||||
MODE="${3:-preview}" # preview | apply
|
||||
|
||||
if [ ! -d "$SOURCE_DIR/.git" ]; then
|
||||
echo "错误:$SOURCE_DIR 不是一个 git 仓库根目录" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "$TARGET_DIR" ]; then
|
||||
echo "错误:目标目录不存在:$TARGET_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 只同步工程项目本身的文件,Claude Code 相关的配置/记忆文件(CLAUDE.md、.claude/ 目录,
|
||||
# 包括其中的 skills/commands 等)两个仓库各自独立维护,不参与同步。
|
||||
is_excluded() {
|
||||
local path="$1"
|
||||
case "$path" in
|
||||
.claude/*|.claude) return 0 ;;
|
||||
CLAUDE.md|*/CLAUDE.md) return 0 ;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
# --no-renames:把 rename 拆成"删除旧路径 + 新增新路径"两条记录,避免解析组合格式
|
||||
# --untracked-files=all:新增的整个目录也会逐个文件列出,而不是折叠成一行目录
|
||||
# -z:以 NUL 分隔,规避文件名转义/含空格的问题
|
||||
copy_list=()
|
||||
delete_list=()
|
||||
excluded_list=()
|
||||
|
||||
while IFS= read -r -d '' entry; do
|
||||
status="${entry:0:2}"
|
||||
path="${entry:3}"
|
||||
[ -z "$path" ] && continue
|
||||
if is_excluded "$path"; then
|
||||
excluded_list+=("$status|$path")
|
||||
continue
|
||||
fi
|
||||
if [ -e "$SOURCE_DIR/$path" ]; then
|
||||
copy_list+=("$status|$path")
|
||||
else
|
||||
delete_list+=("$status|$path")
|
||||
fi
|
||||
done < <(git -C "$SOURCE_DIR" status --porcelain=v1 -z --no-renames --untracked-files=all)
|
||||
|
||||
echo "源目录: $SOURCE_DIR"
|
||||
echo "目标目录: $TARGET_DIR"
|
||||
echo ""
|
||||
echo "=== 待复制/覆盖(${#copy_list[@]})==="
|
||||
for item in "${copy_list[@]+"${copy_list[@]}"}"; do
|
||||
echo " [${item%%|*}] ${item#*|}"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== 待删除(${#delete_list[@]})==="
|
||||
for item in "${delete_list[@]+"${delete_list[@]}"}"; do
|
||||
echo " [${item%%|*}] ${item#*|}"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== 已忽略,不参与同步(${#excluded_list[@]})==="
|
||||
for item in "${excluded_list[@]+"${excluded_list[@]}"}"; do
|
||||
echo " [${item%%|*}] ${item#*|}"
|
||||
done
|
||||
|
||||
if [ "$MODE" != "apply" ]; then
|
||||
echo ""
|
||||
echo "(预览模式,未执行任何操作。确认无误后加 apply 参数执行同步)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
copied=0
|
||||
deleted=0
|
||||
|
||||
for item in "${copy_list[@]+"${copy_list[@]}"}"; do
|
||||
path="${item#*|}"
|
||||
mkdir -p "$(dirname "$TARGET_DIR/$path")"
|
||||
cp -f "$SOURCE_DIR/$path" "$TARGET_DIR/$path"
|
||||
copied=$((copied+1))
|
||||
done
|
||||
|
||||
for item in "${delete_list[@]+"${delete_list[@]}"}"; do
|
||||
path="${item#*|}"
|
||||
if [ -e "$TARGET_DIR/$path" ]; then
|
||||
rm -f "$TARGET_DIR/$path"
|
||||
deleted=$((deleted+1))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "同步完成:复制/更新 $copied 个文件,删除 $deleted 个文件。"
|
||||
Reference in New Issue
Block a user