725 字
4 分钟
在 macOS 上用 Zsh 实现目录变更防抖自动 Git 提交

在 macOS 上用 Zsh 实现目录变更防抖自动 Git 提交#

在日常写博客或代码时,我们经常会希望:文件夹里的内容一旦有变化,自动执行 git add/commit/push

但如果我们在编辑过程中保存了很多次,就可能触发频繁提交。

解决方案就是 —— 防抖(debounce):只有当文件夹安静一段时间后,再提交一次。

本文介绍如何在 macOS 上实现这一需求。


背景问题#

很多 Linux 脚本会使用 /dev/shm 来存储共享状态,因为这是一个基于内存的文件系统。

但是在 macOS 上,没有 /dev/shm。常见的替代方式有两种:

  • 使用 /tmp(实际上是 /private/tmp),会在重启后清空,非常适合做临时文件。

  • 自行挂载 RAM Disk,但这对大多数场景来说太复杂。

因此我们最终选择:在 /tmp 下存放一个状态文件


脚本逻辑#

脚本主要分为三个部分:

  1. 监听目录变化:用 fswatch 来检测文件夹的改动。

  2. 记录提交时间点:每次检测到改动,就把“预计提交时间”刷新到当前时间 + 600 秒(10 分钟)。

  3. 独立定时循环:每隔 5 秒检查一次,如果当前时间超过了“预计提交时间”,则执行 git add/commit/push。

这样就能实现:只要 10 分钟内持续修改,就一直顺延提交时间,直到你停手 ≥10 分钟才会真正提交。


脚本代码#

保存为 auto_commit.sh:

#!/bin/zsh
export 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 minutes
STATE_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"
fi
done

使用方法#

  1. 确保已安装 fswatch
brew install fswatch
  1. 给脚本执行权限:

chmod +x auto_commit.sh
  1. 后台运行:

./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

在 macOS 上用 Zsh 实现目录变更防抖自动 Git 提交
https://blog.lishuyu.top/posts/auto_commit_macos/
作者
猫猫魔女
发布于
2025-09-23
许可协议
CC BY-NC-SA 4.0