在 macOS 上用 Zsh 实现目录变更防抖自动 Git 提交
在日常写博客或代码时,我们经常会希望:文件夹里的内容一旦有变化,自动执行 git add/commit/push。
但如果我们在编辑过程中保存了很多次,就可能触发频繁提交。
解决方案就是 —— 防抖(debounce):只有当文件夹安静一段时间后,再提交一次。
本文介绍如何在 macOS 上实现这一需求。
背景问题
很多 Linux 脚本会使用 /dev/shm 来存储共享状态,因为这是一个基于内存的文件系统。
但是在 macOS 上,没有 /dev/shm。常见的替代方式有两种:
-
使用 /tmp(实际上是 /private/tmp),会在重启后清空,非常适合做临时文件。
-
自行挂载 RAM Disk,但这对大多数场景来说太复杂。
因此我们最终选择:在 /tmp 下存放一个状态文件。
脚本逻辑
脚本主要分为三个部分:
-
监听目录变化:用 fswatch 来检测文件夹的改动。
-
记录提交时间点:每次检测到改动,就把“预计提交时间”刷新到当前时间 + 600 秒(10 分钟)。
-
独立定时循环:每隔 5 秒检查一次,如果当前时间超过了“预计提交时间”,则执行 git add/commit/push。
这样就能实现:只要 10 分钟内持续修改,就一直顺延提交时间,直到你停手 ≥10 分钟才会真正提交。
脚本代码
保存为 auto_commit.sh:
#!/bin/zshexport PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
WATCH_DIR="/Users/yourname/Codes/blog/src/content/posts"REPO_DIR="/Users/yourname/Codes/blog"DEBOUNCE=600 # 10 minutesSTATE_FILE="/tmp/next_commit_$(echo -n "$REPO_DIR" | shasum -a 256 | cut -c1-8)"
commit_and_push() { cd "$REPO_DIR" || exit 1 git add -A if git diff --cached --quiet; then echo "No changes to commit" return fi if git commit -m "auto update from watcher" >/dev/null 2>&1; then git push origin HEAD >/dev/null 2>&1 \ && echo "Pushed at $(date)" \ || echo "Push failed at $(date)" else echo "Commit failed" fi}
trap 'rm -f "$STATE_FILE"' EXIT
# 监听变化:刷新下一次提交时间/opt/homebrew/bin/fswatch -o "$WATCH_DIR" | while read -r _; do now=$(date +%s) ts=$(( now + DEBOUNCE )) tmp="${STATE_FILE}.$$" printf '%s\n' "$ts" > "$tmp" && mv -f "$tmp" "$STATE_FILE" echo "Change detected at $(date). Next commit at $(date -r "$ts")"done &
# 定时器:到点提交while true; do sleep 5 [[ -f "$STATE_FILE" ]] || continue read -r next_commit < "$STATE_FILE" || continue now=$(date +%s) if (( now >= next_commit )); then commit_and_push rm -f "$STATE_FILE" fidone使用方法
- 确保已安装 fswatch:
brew install fswatch-
给脚本执行权限:
chmod +x auto_commit.sh-
后台运行:
./auto_commit.sh &此时,只要你在 WATCH_DIR 目录下修改或新增文件,脚本就会等待 10 分钟,如果期间没有新变化,就自动执行一次 Git 提交和推送。
总结
-
macOS 没有 /dev/shm,所以我们用 /tmp 存储共享状态。
-
利用 fswatch + 防抖逻辑,实现了“停止编辑 ≥10 分钟才自动提交”。
-
这样可以让自动化提交既智能又不会过于频繁。
[!quote] We cannot change our memories, but we can change their meaning and the power they have over us. — David Seamans