tools/update.sh:服务器同步 gh-pages 分支(详解)
这个脚本是干什么的?
tools/update.sh 是一个服务器端同步脚本,目标是:把服务器上的工作目录强制更新到远端 origin/gh-pages 的最新状态。
使用场景
如果你除了 GitHub Pages,还有自己的服务器(比如用宝塔面板搭建的 VPS),想让服务器也提供博客访问,流程是:
- 本地写文章 →
npm run publish→ 推送到 GitHub gh-pages 分支 - 服务器定时或手动执行
update.sh→ 拉取最新静态文件 - Nginx 指向该目录 → 用户访问你的服务器域名就能看到博客
如果你只用 GitHub Pages
这个脚本对你没用。GitHub Pages 会自动从 gh-pages 分支读取内容,你 deploy 之后就上线了,不需要再同步。
用法
在服务器上的仓库目录执行:
bash tools/update.sh |
或者配置 cron 定时任务:
# 每小时同步一次 |
完整源码
|
逐行代码解析
第 1 行:Shebang
- 使用
env bash而不是硬编码/bin/bash,兼容性更好(不同系统 bash 路径可能不同)
第 3 行:严格模式
set -euo pipefail |
三个选项的含义:
-e:任何命令返回非零退出码时立即终止脚本-u:引用未定义变量时报错(防止拼写错误导致空变量)-o pipefail:管道中任一命令失败则整个管道失败
这是 Bash 脚本的最佳实践,能尽早发现问题。
第 5-6 行:定位仓库根目录
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" |
${BASH_SOURCE[0]}:当前脚本的路径(比$0更可靠,支持 source 调用)dirname:取目录部分(即tools/)/..:上一级就是仓库根目录cd ... && pwd:进入目录并输出绝对路径
好处:无论你从哪个目录执行脚本,它都能正确定位到仓库根目录。
第 8-9 行:定义远端和分支
REMOTE="origin" |
变量化便于修改和阅读。
第 11 行:只拉取目标分支
git fetch "$REMOTE" "$BRANCH" |
- 只拉取
gh-pages分支,不拉其他分支(节省带宽和时间) fetch只更新远端引用,不修改工作区
第 12 行:切换到目标分支
git checkout -q "$BRANCH" 2>/dev/null || git checkout -q -b "$BRANCH" "$REMOTE/$BRANCH" |
这是一个"先尝试后回退"的模式:
- 先尝试
checkout gh-pages(本地已有该分支) - 如果失败(本地没有),则创建并跟踪远端分支
-q 是静默模式,2>/dev/null 抑制错误输出。
第 13 行:强制对齐
git reset --hard "$REMOTE/$BRANCH" |
核心操作:把当前工作区强制重置到远端分支的最新状态。
- 本地未提交的修改会被覆盖
- 本地比远端多的提交会被丢弃
这正是我们要的效果:服务器只是"镜像",不应该有本地修改。
第 15-19 行:宝塔权限修复(可选)
if [ -f "/etc/init.d/bt" ] && id -u www >/dev/null 2>&1; then |
逻辑分解:
[ -f "/etc/init.d/bt" ]:检测是否是宝塔面板环境id -u www:检测是否存在www用户(宝塔默认 Web 服务用户)- 如果都满足,尝试把目录所有权改为
www || true:即使 chown 失败也不中断脚本(best-effort)
为什么需要:Nginx 以 www 用户运行,需要读取权限。如果你用 root 执行同步,文件权限可能不对。
注意事项
- 这是破坏性操作:本地修改会被覆盖,请确保服务器上的仓库只用于"镜像"
- 不清理未跟踪文件:如果远端删了某个文件,本地可能残留。如需清理:
git clean -fd # 删除未跟踪的文件和目录
- 首次使用前:确保服务器上已经
git clone过仓库
与 hexo deploy 的关系
hexo deploy 做的事情:
- 把
public/目录推送到 gh-pages 分支
update.sh 做的事情:
- 把 gh-pages 分支的内容拉到服务器
它们是互补的,不是替代关系。如果你只用 GitHub Pages,不需要 update.sh。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 HExLL-迷雾日志!