如何在Git post-receive钩子中检查工作副本是否已更新?
解决Git自动部署中仅在分支更新时执行deploy.sh的问题
由于git pull无论是否有代码更新都会返回0,无法通过返回值判断是否需要执行部署脚本,你可以通过以下两种方法实现仅在工作副本真的更新时才运行deploy.sh:
方法1:对比pull前后的HEAD提交哈希
记录执行git pull前后当前分支的HEAD哈希值,若两者不同则说明有代码更新,再触发部署:
# 处理master分支对应的生产站点 cd /var/www/mysite.example unset GIT_DIR # 获取pull前的HEAD哈希 before=$(git rev-parse HEAD) git pull origin master # 获取pull后的HEAD哈希 after=$(git rev-parse HEAD) # 哈希不一致则执行部署 if [ "$before" != "$after" ]; then ./deploy.sh fi # 处理dev分支对应的测试站点 cd /var/www/dev.mysite.example unset GIT_DIR before=$(git rev-parse HEAD) git pull origin dev after=$(git rev-parse HEAD) if [ "$before" != "$after" ]; then ./deploy.sh fi
方法2:拆分git pull为fetch+merge,提前判断分支差异
将git pull拆分为git fetch和git merge两步,先检查本地分支与远程分支是否存在差异,有差异再合并并执行部署:
# 处理master分支对应的生产站点 cd /var/www/mysite.example unset GIT_DIR git fetch origin master # 检查本地HEAD与远程master是否无差异 if git diff --quiet HEAD origin/master; then echo "master分支已保持最新,跳过部署" else git merge origin/master ./deploy.sh fi # 处理dev分支对应的测试站点 cd /var/www/dev.mysite.example unset GIT_DIR git fetch origin dev if git diff --quiet HEAD origin/dev; then echo "dev分支已保持最新,跳过部署" else git merge origin/dev ./deploy.sh fi
两种方法的差异:
- 方法1逻辑简单直接,仅通过HEAD变化判断更新,适合大多数场景;
- 方法2更灵活,可自定义合并策略(比如添加
--ff-only参数强制快进合并),也能避免git pull默认行为带来的意外。
内容的提问来源于stack exchange,提问作者androkettle
相关产品推荐
相关产品推荐

