能否合并两个仅含blob和tree对象的Git内容寻址存储?
合并两个仅含Blob/Tree的Git仓库的可行方案
最简方案:仅整合Blob和Tree(直接复用Git工具)
完全可以合并,Git的内容寻址特性决定了只要把两个仓库的对象集合到一起就行,用原生Git命令就能搞定,步骤如下:
- 新建一个空仓库作为整合目标:
git init target-repo - 进入目标仓库,把第一个源仓库设为远程:
git remote add repo1 /本地路径/到/第一个仓库 - 执行
git fetch repo1,Git会自动拉取该仓库所有存在的Blob和Tree对象(哪怕没有分支或Commit) - 重复上述步骤添加第二个源仓库并拉取:
git remote add repo2 /本地路径/到/第二个仓库,再跑git fetch repo2 - 搞定后,目标仓库的
.git/objects已经包含了两个源仓库的所有对象。
要是源仓库没法用远程方式访问,直接复制文件也行:
- 把两个源仓库
.git/objects下的所有哈希子目录(排除pack和info)复制到目标仓库的对应目录;如果有pack压缩包,先跑git unpack-objects < pack-file解压,再复制,或者直接复制pack文件后用git repack合并成新的压缩包。
处理Commit对象的方法(确实容易)
不管是源仓库后续要加Commit,还是你想给整合后的Tree生成Commit,都很直观:
- 如果源仓库已经有Commit,
git fetch会自动把Commit连同它关联的Tree、Blob一起拉过来,不需要额外操作; - 要给整合后的结构造新Commit的话,先把工作区切换到目标Tree:
git read-tree <目标Tree的哈希值>,然后执行git commit -m "整合两个仓库的初始目录结构",生成的Commit就会关联所有导入的对象。
处理Tag对象的注意事项
Tag可以指向Commit、Tree甚至Blob,处理时要注意关联关系:
- 拉取源仓库的Tag直接用
git fetch --tags,Git会自动把Tag指向的对象及其依赖都拉到目标仓库; - 如果是直接打在Tree或Blob上的Tag,拉取后直接用
git show <标签名>就能查看对应的内容; - 手动给导入的Tree/Blob打Tag也简单:
git tag -a <标签名> <Tree/Blob哈希> -m "标记整合后的内容"。
分支/Reference指针的处理方式
分支本质是指向Commit的指针,哪怕源仓库现在没有Commit,后续要关联分支的话这么做:
- 拉取源仓库分支时用
git fetch repo1 refs/heads/*:refs/remotes/repo1/*,这样会把源仓库的分支作为远程跟踪分支导入到目标仓库; - 如果源仓库分支有Commit,直接切换到目标仓库的本地分支,执行
git merge repo1/<分支名>就能合并; - 要是源仓库分支只有Tree没有Commit,先基于该Tree创建Commit再关联分支:
git checkout -b <新分支名>,然后git read-tree <Tree哈希>,最后git commit -m "初始化分支结构"。
内容的提问来源于stack exchange,提问作者Corbin
相关产品推荐
相关产品推荐

