我有一堆git存储库,每个包含一个文件.我想将它们合并在一起,最好是一步到位.我的目标是这个图:
*----¬ mergedrepo/master
| \ \ \
| | | * repoA/master
| | * repoB/master
| | |
| | * repoB/...
| * repoC/master
* repoD/master
|
* repoD/...
Run Code Online (Sandbox Code Playgroud)
我试过了git merge,但看起来章鱼策略不适用于不相交的树木
$ git merge a/master b/master c/master d/master
Unable to find common commit with a/master
Automatic merge failed; fix conflicts and then commit the result.
Run Code Online (Sandbox Code Playgroud)
我也被告git merge --squash知会有所帮助,但这也给出了同样的错误.
这会生成正确的图形,但会丢失所有文件:
$ git merge -s ours a/master b/master c/master d/master
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?
Ver*_*igo 14
我已经设法用章鱼合并不相关的分支来解决问题.遗憾的是,以下内容仅适用于不存在真正合并冲突的相当简单的情况.
按照OP中的描述进行合并.
git merge --allow-unrelated-histories a/master b/master c/master d/master
它将"失败"声称冲突.但是合并已经完成并且事实记录了,尽管索引没有变化.
使用以下read-tree命令将分支内容添加到索引:
git read-tree a/master b/master c/master d/master
这不会影响工作树,只会更新索引.(您可能希望将当前分支添加到最后.您需要在一个命令中添加所有分支.)
如果分支不是完全独立的,那么调整它们的顺序,记住后者将覆盖以前分支的内容.
git commit -m "octopus-merged remote 'a', 'b', 'c', 'd'")git reset --hard)以获得一致的工作树.我想以后可以编辑和修改这个提交,但我个人没有试过这个.
创建一个空的提交
git commit -m "Common commit" --allow-empty
Run Code Online (Sandbox Code Playgroud)
查看它的哈希值并将log -1其添加到没有任何父项的移植文件中
echo HASH_OF_COMMON_COMMIT >> .git/info/grafts
Run Code Online (Sandbox Code Playgroud)
然后找到所有其他根,log --max-parents=0并为每个将它们的散列添加到移植文件中,并以上述散列作为父项
each HASH_OF_ROOT HASH_OF_COMMON_COMMIT >> .git/info/grafts
Run Code Online (Sandbox Code Playgroud)
现在,合并!
移植文件是一种更改提交的父级的方法,一旦您的所有存储库都有一个共同的提交,您的存储库应该接受合并。
我有很多不相关的分支需要从遗留的 SVN 结构合并到新初始化的 Git 存储库。Vertigo的答案让我明白了大部分内容,但git read-tree一次最多只能读取 8 棵树。
我的解决方案是在每次读取后编写一棵新树,然后在下一次读取中使用该新树:
tree_head=HEAD
to_merge="a/master ... z/master"
# If you're using a variable here you want word splitting, so don't use quotes.
git merge --allow-unrelated-histories $to_merge
for merging in $to_merge; do
git read-tree "$tree_head" "$merging"
tree_head=$(git write-tree)
done
git checkout-index -fua
git commit -m "All repos merged."
Run Code Online (Sandbox Code Playgroud)