diff --git a/track-uniapp/sync-watch.sh b/track-uniapp/sync-watch.sh index 161145f..d3719c8 100644 --- a/track-uniapp/sync-watch.sh +++ b/track-uniapp/sync-watch.sh @@ -1,29 +1,117 @@ #!/bin/bash # ============================================================ -# uni-app 双向同步脚本 -# WSL ←→ Windows G 盘,两边改代码互相跟随 -# 用法: bash sync-watch.sh 停止: Ctrl+C +# track-uniapp 源码 → HBuilderX 项目 同步 +# +# 方向:单向 WSL track-uniapp/src/ → G:\Track\track-app\track +# +# ⚠️ 为什么是「src/ → 项目根」且单向(2026-09-15 修正): +# HBuilderX 是以 G:\Track\track-app\track 为项目根打开的(经典布局, +# pages.json / App.vue / manifest.json 都在根目录),该目录就是 +# track-uniapp/src/ 的**扁平镜像** —— 证据:test_wgt_local.bat 里写着 +# "Please build WGT in HBuilderX first",且两侧文件时间戳逐项吻合。 +# +# 旧版脚本按 track-uniapp/ ↔ track-app/track/ 双向对拷,方向完全错误: +# · 正向会把 src/ 整个塞成 track/src/,并用 WSL 的 index.html 覆盖 +# HBuilderX 的入口文件; +# · 反向会把 Windows 项目根的文件搬回 WSL 根目录,让已清理的 +# 「幽灵文件」复活。 +# 故改为单向,且显式排除所有「只在 Windows 侧存在」的项。 +# +# 用法: +# bash sync-watch.sh # 同步一次,然后持续监听(推荐) +# bash sync-watch.sh once # 只同步一次 +# bash sync-watch.sh dry # 只预览差异,不落盘 +# 停止: Ctrl+C # ============================================================ -SRC="/home/yueli/track/track-uniapp" +SRC="/home/yueli/track/track-uniapp/src" DST="/mnt/g/Track/track-app/track" -EXCLUDES="--exclude node_modules --exclude .git --exclude dist --exclude unpackage --exclude .hbuilderx --exclude package.json --exclude package-lock.json --exclude vite.config.ts --exclude uni.scss --exclude uni.promisify.adaptor.js" +# ── 只在 Windows 侧存在、绝对不能被覆盖或删除的项 ── +EXCLUDES=( + # manifest.json 的版本号(T1.0.44)与存储权限只在 HBuilderX 里维护。 + # WSL 那份停留在 T1.0.8,是过期副本 —— 同步过去会回退版本号并抹掉权限。 + --exclude 'manifest.json' + # HBuilderX 经典布局特有,src/ 里没有对应物 + --exclude 'index.html' + --exclude 'static/' + --exclude 'uni.scss' + --exclude 'uni.promisify.adaptor.js' + --exclude '.editorconfig' + --exclude '.gitignore' + --exclude '.hbuilderx/' + # HBuilderX 的 WGT 构建产物(约 216M) + --exclude 'unpackage/' + --exclude 'node_modules/' + --exclude '.git/' + # 手工备份(如 pages/scan/detail.vue.bak-20260914) + --exclude '*.bak-*' + --exclude '*.wgt' +) + +# --delete 让「在 WSL 删掉的文件」在 Windows 侧同步消失(如已废弃的 +# FlowTree.vue / TaskTreeNode.vue)。被 --exclude 命中的项不受 --delete +# 影响,所以上面的白名单不会被误删。 +# +# 不用 -a:目标 /mnt/g 是 drvfs,POSIX 权限/属主都是合成的(恒为 777), +# -a 里的 -p/-o/-g 每次都会判定为「有差异」→ 无谓 chmod + 刷屏的 p 标记。 +# 保留 -r(递归)+ -t(时间戳,两侧时间戳本就是同步依据)。 +RSYNC_OPTS=(-rlt --delete "${EXCLUDES[@]}" --no-perms --no-owner --no-group) do_sync() { - rsync -av $EXCLUDES "$SRC/" "$DST/" 2>/dev/null - sleep 0.5 - rsync -av $EXCLUDES "$DST/" "$SRC/" 2>/dev/null + case "$1" in + dry) + echo "🔍 预览模式(不落盘):" + rsync "${RSYNC_OPTS[@]}" --dry-run --itemize-changes "$SRC/" "$DST/" + ;; + *) + rsync "${RSYNC_OPTS[@]}" --itemize-changes "$SRC/" "$DST/" + local rc=$? + if [ $rc -eq 0 ]; then + echo " ↻ $(date +%H:%M:%S) 已同步" + else + # 不吞错误:旧脚本 2>/dev/null 把 rsync 的报错全丢了,出了问题只能干瞪眼 + echo " ❌ $(date +%H:%M:%S) rsync 退出码 $rc —— 同步可能不完整,请检查" + fi + ;; + esac } -echo "🔁 双向同步 $SRC ↔ $DST" -echo " 按 Ctrl+C 停止" +case "$1" in + dry) + do_sync dry + exit 0 + ;; + once) + do_sync + exit 0 + ;; +esac + +echo "🔁 单向同步 $SRC → $DST" do_sync echo "✅ 首次同步完成,开始监听..." -inotifywait -m -r -e modify,create,delete,move \ - --exclude 'node_modules|.git|dist|unpackage|.hbuilderx' \ - "$SRC" 2>/dev/null | while read -r dir action file; do - do_sync - echo " ↻ $(date +%H:%M:%S) 已同步" -done +if command -v inotifywait >/dev/null 2>&1; then + echo "👀 inotifywait 实时监听中(Ctrl+C 停止)" + inotifywait -m -r -e modify,create,delete,move \ + --exclude 'node_modules|\.git|dist|unpackage|\.hbuilderx' \ + "$SRC" | while read -r _dir _action _file; do + do_sync + done +else + # 旧脚本在这里静默失败过:inotifywait 没装,2>/dev/null 又把报错吞了, + # 表现为「脚本像是跑着,但改了代码 G 盘一直不更新」。改为明确提示 + 轮询兜底。 + echo "⚠️ inotifywait 未安装,退回轮询模式(每 3 秒比对一次)" + echo " 想要实时监听: sudo apt install -y inotify-tools" + echo " Ctrl+C 停止" + last="" + while true; do + cur=$(find "$SRC" -type f -printf '%T@ %p\n' 2>/dev/null | sort | md5sum) + if [ "$cur" != "$last" ]; then + [ -n "$last" ] && do_sync + last="$cur" + fi + sleep 3 + done +fi