Git:在分支间共享指定文件夹并保留提交历史
作为Git新手碰到这种跨分支共享目录的问题很正常,我来给你拆解几个可行的方案,帮你实现「sun」文件夹在所有分支间的变更同步,同时完整保留提交历史:
方案一:使用Git Subtree Merge(推荐,无需拆分仓库)
这个方法可以把「sun」的内容单独维护在一个专用分支,然后在其他分支里把这个分支合并到solar system/sun目录下,后续更新时只需同步这个专用分支即可:
创建「sun-shared」专用分支
先从「sun work」分支(它已经有完整的sun目录)创建一个专门维护sun的分支:git checkout "sun work" git checkout -b sun-shared # 把分支里只保留sun相关内容,删除其他无关文件 git rm -r . --exclude="solar system/sun" git commit -m "Initialize sun-shared branch with only sun directory"在其他分支合并sun-shared分支到指定目录
以「earth tests」分支为例:git checkout "earth tests" # 把sun-shared分支合并到当前分支的solar system/sun目录 git merge -s subtree --no-commit sun-shared # 检查合并后的目录结构,确认sun文件夹内容正确 git add . git commit -m "Merge sun-shared into solar system/sun"对「mars tests」分支重复上述操作即可。
同步sun的变更到所有分支
以后不管在哪个分支修改了sun文件夹,都先把变更同步到sun-shared分支:# 比如在earth tests分支修改了sun内容后: git checkout sun-shared # 把earth tests分支的sun目录内容拉过来 git checkout "earth tests" -- "solar system/sun" git commit -m "Update sun from earth tests" # 然后切换到其他分支合并sun-shared的更新 git checkout "mars tests" git merge -s subtree sun-shared这样所有分支的sun内容都会同步,且完整保留提交历史。
方案二:使用Git子模块(适合长期独立维护sun)
如果「sun」文件夹的内容后续会有大量独立开发需求,可以把它拆成一个独立的Git仓库,然后作为子模块嵌入到各个分支中:
创建独立的sun仓库
把现有仓库里的solar system/sun目录单独拎出来做成新仓库:# 在本地新建一个sun仓库 mkdir sun-repo && cd sun-repo git init # 把原仓库的sun内容复制过来 cp -r /path/to/original/repo/solar\ system/sun/* . git add . git commit -m "Initialize sun repository"在原仓库各分支添加子模块
切换到「earth tests」分支:cd /path/to/original/repo git checkout "earth tests" # 删除原有的sun目录 rm -r "solar system/sun" git commit -m "Remove local sun directory" # 添加sun子模块到指定目录 git submodule add /path/to/sun-repo "solar system/sun" git add . git commit -m "Add sun submodule"对「mars tests」和「sun work」分支重复上述操作。
同步变更
以后修改sun内容时,直接进入子模块目录提交,然后在主仓库各分支拉取子模块的最新版本即可:cd "solar system/sun" git add . git commit -m "Update sun content" git push # 在主仓库更新子模块 cd ../.. git submodule update --remote git add . git commit -m "Update sun submodule to latest version"
方案三:手动Cherry-Pick提交(适合临时少量变更)
如果只是偶尔同步少量提交,可以用git cherry-pick把sun相关的提交单独复制到其他分支:
找到sun相关的提交哈希
在修改sun的分支里,用以下命令查看所有涉及sun的提交,记下对应的哈希值:git log --oneline -- "solar system/sun"切换到目标分支并Cherry-Pick
git checkout "mars tests" git cherry-pick <sun-commit-hash>这个方法简单但适合变更少的场景,频繁同步的话会比较繁琐。
内容的提问来源于stack exchange,提问作者Alexander G.

