推送非master分支至远程时Git post-receive钩子失效问题排查
解决Git多分支推送至Staging服务器的异常问题
根据你的场景描述,核心问题大概率出在post-receive钩子脚本的逻辑设计上——毕竟master分支能正常推送并触发同步,但新分支不行,说明钩子可能只针对master分支做了处理,完全没适配其他分支的推送场景。下面是具体的排查和修复方案:
一、先检查现有post-receive钩子的逻辑
登录到staging服务器,找到裸仓库下的hooks/post-receive文件,查看里面的代码。这类同步脚本通常会有类似这样的分支判断:
#!/bin/bash while read oldrev newrev refname do # 只处理master分支 if [[ $refname == "refs/heads/master" ]]; then git --work-tree=/path/to/public_html --git-dir=/path/to/bare/repo checkout -f master fi done
如果你的脚本里只有针对master的判断,那新分支推送时,钩子根本不会执行同步操作,自然会出现“推送异常”的表现(比如public_html里看不到新分支的内容)。
二、修改钩子适配多分支推送需求
结合你要搭建本地、staging、生产三个环境的目标,分两种常见场景调整钩子:
场景1:每个分支对应staging的独立目录
如果希望不同分支推送到staging时,同步到不同的子目录(比如public_html/feature-user-center对应feature-user-center分支),可以把钩子改成这样:
#!/bin/bash # 定义staging的基础目录 BASE_STAGING_DIR="/path/to/public_html" while read oldrev newrev refname do # 从refname里提取分支名(比如从refs/heads/feature-x得到feature-x) BRANCH_NAME=$(basename "$refname") # 创建对应分支的目录(不存在则自动创建) mkdir -p "$BASE_STAGING_DIR/$BRANCH_NAME" # 将分支内容同步到对应目录 git --work-tree="$BASE_STAGING_DIR/$BRANCH_NAME" --git-dir=/path/to/bare/repo checkout -f "$BRANCH_NAME" echo "✅ 成功同步分支 $BRANCH_NAME 到 $BASE_STAGING_DIR/$BRANCH_NAME" done
场景2:指定分支同步到主public_html目录
如果只希望master和特定分支(比如dev、pre-staging分支)同步到主public_html目录,其他分支仅存于裸仓库不做同步,可以调整判断逻辑:
#!/bin/bash TARGET_DIR="/path/to/public_html" # 允许同步到主目录的分支列表 ALLOWED_BRANCHES=("master" "dev" "pre-staging") while read oldrev newrev refname do BRANCH_NAME=$(basename "$refname") # 检查当前分支是否在允许列表中 if [[ " ${ALLOWED_BRANCHES[@]} " =~ " ${BRANCH_NAME} " ]]; then git --work-tree="$TARGET_DIR" --git-dir=/path/to/bare/repo checkout -f "$BRANCH_NAME" echo "✅ 已同步分支 $BRANCH_NAME 到主目录 $TARGET_DIR" else echo "ℹ️ 分支 $BRANCH_NAME 不在允许同步列表中,跳过同步操作" fi done
三、确保钩子脚本的权限正确
修改完钩子后,一定要给脚本加上可执行权限,否则Git无法触发它:
chmod +x /path/to/bare/repo/hooks/post-receive
四、测试新分支推送
回到本地仓库,创建并推送新分支验证:
# 创建并切换到新分支 git checkout -b feature-new-function # 做一些修改后提交 git add . && git commit -m "新增功能:用户导出" # 推送到staging服务器的对应分支 git push origin feature-new-function
之后登录staging服务器,查看对应的目录是否已经同步了新分支的内容。如果还是有异常,可以在钩子脚本里添加日志输出(比如把操作记录写到/var/log/git_sync.log),进一步定位问题。
内容的提问来源于stack exchange,提问作者AlexGHooper
相关产品推荐
相关产品推荐

