如何实现Git仓库repo-A指定子文件夹的变更同步至repo-B并保留提交历史
最优同步方案推荐(针对Repo-A -> Repo-B的folder1/folder2同步)
我之前帮团队处理过几乎一模一样的仓库拆分+临时同步场景,结合Git的最佳实践,给你按优先级推荐三个方案:
方案1:Git Subtree(最推荐,灵活可扩展)
这个方案适合长期临时同步,甚至之后Repo-B稳定了,还能支持双向同步(把Repo-B的变更回推到Repo-A),而且操作简单,不需要复杂的服务器配置。
步骤:
- 在Repo-B本地仓库中添加Repo-A为远程源:
git remote add repo-A <你的Repo-A远程URL> git fetch repo-A
- 首次将Repo-A的folder1/folder2合并到Repo-B对应位置:
# 同步folder1 git subtree add --prefix=folder1 repo-A master:folder1 # 同步folder2 git subtree add --prefix=folder2 repo-A master:folder2
- 后续定期同步Repo-A的最新变更:
每次Repo-A有新提交后,在Repo-B中运行:
git subtree pull --prefix=folder1 repo-A master:folder1 git subtree pull --prefix=folder2 repo-A master:folder2
- (可选)自动同步:
如果想完全自动化,可以把上述同步命令加到CI/CD流水线中,比如每次Repo-A的master分支有push,就触发CI运行同步脚本。
方案2:Post-Receive钩子 + Git Filter-Repo(自动触发,适合无人值守)
如果需要每次开发push到Repo-A就自动同步,可以用远程仓库的post-receive钩子配合Git Filter-Repo(官方推荐替代filter-branch的工具,更高效稳定)。
步骤:
- 在Repo-A的远程服务器仓库(比如
~/repo-A.git)中,创建hooks/post-receive脚本:
#!/bin/bash # 替换为你的Repo-B本地仓库路径(服务器上的克隆版本) REPO_B_LOCAL="/var/repos/repo-B" # 替换为你的Repo-A远程URL REPO_A_URL="ssh://git@your-server.com/repos/repo-A.git" # 切换到Repo-B目录并拉取Repo-A最新内容 cd "$REPO_B_LOCAL" git fetch repo-A # 使用filter-repo同步指定文件夹 git filter-repo --path folder1 --path folder2 --from-repo "$REPO_A_URL" --force # 推送到Repo-B的远程仓库 git push origin master
- 给脚本添加执行权限:
chmod +x ~/repo-A.git/hooks/post-receive
注意:需要在服务器上安装Git Filter-Repo(依赖Python3),而且要确保Repo-B是服务器上的一个完整克隆仓库(不是裸仓库)。
方案3:手动同步脚本(临时应急,快速上手)
如果只是短期过渡,不想折腾配置,可以写一个简单的shell脚本手动触发同步:
脚本内容(save as sync-repos.sh):
#!/bin/bash # 替换为你的仓库URL REPO_A_URL="<Repo-A远程URL>" REPO_B_URL="<Repo-B远程URL>" # 临时克隆Repo-A并提取指定文件夹 git clone "$REPO_A_URL" temp-repo cd temp-repo git filter-repo --path folder1 --path folder2 # 推送到Repo-B git remote add repo-b "$REPO_B_URL" git push repo-b master --force # 清理临时文件 cd .. rm -rf temp-repo
运行前给脚本加权限:
chmod +x sync-repos.sh
注意:
--force会覆盖Repo-B的对应文件夹内容,如果Repo-B有自主开发的变更,一定要先拉取并解决冲突后再运行。
关键注意事项
- 禁止使用
git filter-branch:官方已经明确废弃这个命令,它速度慢且容易出问题,Git Filter-Repo是官方推荐的替代工具。 - 冲突处理:如果Repo-B之后有自己的开发,同步前一定要先拉取Repo-B的最新代码,手动解决冲突后再推送。
- 过渡完成后:当Repo-B稳定,开发人员切换到Repo-B后,记得移除同步机制,避免双向冲突。
内容的提问来源于stack exchange,提问作者Sreeraj TR
相关产品推荐
相关产品推荐

