You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Git钩子实现私有仓库A提交后自动同步至仓库B?

我来分享几个靠谱的方案,既能实现自动同步,又能完美适配SourceTree这类GUI工具——毕竟你提到Shell脚本只适配命令行提交,那咱们得找不受客户端工具限制的方法:

方案一:仓库A的服务器端Post-Receive钩子(最推荐)

不管你用命令行、SourceTree还是其他GUI工具推送代码到A,只要代码推送到A的远程服务器,这个钩子就会自动触发,完全不受客户端环境影响。步骤如下:

  1. 登录仓库A的服务器,找到A的裸仓库路径(一般是类似/var/git/repos/A.git的目录,托管平台的话可能需要通过后台或SSH访问)
  2. 进入仓库下的hooks目录,创建一个名为post-receive的文件(注意不要加任何后缀)
  3. 往文件里写入以下脚本(根据你的实际仓库信息调整):
#!/bin/bash
# 替换成仓库B的远程地址(支持SSH或HTTPS,推荐SSH免密)
B_REPO="ssh://your-username@your-server/var/git/repos/B.git"
# 创建临时目录用来操作B仓库
TMP_DIR=$(mktemp -d)

# 克隆B仓库到临时目录
git clone $B_REPO $TMP_DIR
cd $TMP_DIR

# 读取推送的分支信息(处理多分支场景)
while read oldrev newrev refname; do
    # 获取推送的分支名,比如main、dev
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    
    # 只同步你关心的分支(比如只同步main分支)
    if [ "$branch" = "main" ]; then
        # 拉取A仓库的最新分支内容到本地B仓库
        git pull ssh://your-username@your-server/var/git/repos/A.git $branch
        
        # 如果需要精准同步刚推送的那一个提交,把上面的pull换成cherry-pick:
        # git cherry-pick $newrev
        
        # 推送到B仓库的远程
        git push origin $branch
    fi
done

# 清理临时目录,避免占用空间
rm -rf $TMP_DIR
  1. 给脚本添加执行权限:chmod +x post-receive
  2. 关键配置:确保服务器上运行钩子的用户有访问B仓库的权限(比如配置SSH免密登录,把服务器的公钥添加到B仓库的授权列表里)
方案二:用CI/CD工具实现(适合托管平台仓库)

如果你的仓库是托管在GitLab、GitHub、Gitee这类平台上,用它们自带的CI/CD工具会更灵活,还能看到同步日志,排查问题也方便。以GitHub Actions为例,步骤如下:

  1. 在仓库A的根目录创建.github/workflows/sync-to-b.yml文件
  2. 写入以下配置(按需调整):
name: 自动同步到仓库B
on:
  # 监听main分支的推送事件
  push:
    branches: [ main ]

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      # 拉取仓库A的代码
      - name: 拉取仓库A
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # 拉取完整提交历史,避免cherry-pick失败

      # 配置Git身份(必填,否则推送会失败)
      - name: 配置Git用户信息
        run: |
          git config --global user.name "你的名字"
          git config --global user.email "你的邮箱"

      # 添加仓库B为远程仓库
      - name: 关联仓库B
        run: git remote add b ${{ secrets.B_REPO_URL }}

      # 同步代码到B仓库
      - name: 推送到仓库B
        run: |
          # 方式1:直接合并最新分支(适合完全同步)
          git push b main:main
          
          # 方式2:只同步刚推送的那个提交(替换上面的push命令)
          # git cherry-pick $GITHUB_SHA
          # git push b main
  1. 在仓库A的Settings -> Secrets and variables -> Actions里,添加名为B_REPO_URL的密钥,值为仓库B的SSH地址(比如git@github.com:your-username/B.git),同时要把GitHub Actions的公钥添加到B仓库的授权列表中
为什么不推荐本地钩子(比如post-commit)?

本地钩子是在你的电脑上触发的,SourceTree这类GUI工具可能不会加载你系统的Shell环境,导致钩子脚本无法正常运行;而且如果你在多台电脑提交代码,每台都要配置一遍钩子,维护成本太高,所以不适合你的需求。


内容的提问来源于stack exchange,提问作者Avery235

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:25:14